1<?php
2/**
3 * Project:     Smarty: the PHP compiling template engine
4 * File:        smarty_internal_utility.php
5 * SVN:         $Id: $
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 *
21 * For questions, help, comments, discussion, etc., please join the
22 * Smarty mailing list. Send a blank e-mail to
23 * smarty-discussion-subscribe@googlegroups.com
24 *
25 * @link http://www.smarty.net/
26 * @copyright 2008 New Digital Group, Inc.
27 * @author Monte Ohrt <monte at ohrt dot com>
28 * @author Uwe Tews
29 * @package Smarty
30 * @subpackage PluginsInternal
31 * @version 3-SVN$Rev: 3286 $
32 */
33
34/**
35 * Utility class
36 *
37 * @package Smarty
38 * @subpackage Security
39 */
40class Smarty_Internal_Utility
41{
42    /**
43     * private constructor to prevent calls creation of new instances
44     */
45    final private function __construct()
46    {
47        // intentionally left blank
48    }
49
50    /**
51     * Compile all template files
52     *
53     * @param  string  $extension     template file name extension
54     * @param  bool    $force_compile force all to recompile
55     * @param  int     $time_limit    set maximum execution time
56     * @param  int     $max_errors    set maximum allowed errors
57     * @param  Smarty  $smarty        Smarty instance
58     * @return integer number of template files compiled
59     */
60    public static function compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, Smarty $smarty)
61    {
62        // switch off time limit
63        if (function_exists('set_time_limit')) {
64            @set_time_limit($time_limit);
65        }
66        $smarty->force_compile = $force_compile;
67        $_count = 0;
68        $_error_count = 0;
69        // loop over array of template directories
70        foreach ($smarty->getTemplateDir() as $_dir) {
71            $_compileDirs = new RecursiveDirectoryIterator($_dir);
72            $_compile = new RecursiveIteratorIterator($_compileDirs);
73            foreach ($_compile as $_fileinfo) {
74                $_file = $_fileinfo->getFilename();
75                if (substr(basename($_fileinfo->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false || strpos($_file, '.git') !== false) continue;
76                if (!substr_compare($_file, $extension, - strlen($extension)) == 0) continue;
77                if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
78                   $_template_file = $_file;
79                } else {
80                   $_template_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file;
81                }
82                echo '<br>', $_dir, '---', $_template_file;
83                flush();
84                $_start_time = microtime(true);
85                try {
86                    $_tpl = $smarty->createTemplate($_template_file,null,null,null,false);
87                    if ($_tpl->mustCompile()) {
88                        $_tpl->compileTemplateSource();
89                        $_count++;
90                        echo ' compiled in  ', microtime(true) - $_start_time, ' seconds';
91                        flush();
92                    } else {
93                        echo ' is up to date';
94                        flush();
95                    }
96                } catch (Exception $e) {
97                    echo 'Error: ', $e->getMessage(), "<br><br>";
98                    $_error_count++;
99                }
100                // free memory
101                $smarty->template_objects = array();
102                $_tpl->smarty->template_objects = array();
103                $_tpl = null;
104                if ($max_errors !== null && $_error_count == $max_errors) {
105                    echo '<br><br>too many errors';
106                    exit();
107                }
108            }
109        }
110
111        return $_count;
112    }
113
114    /**
115     * Compile all config files
116     *
117     * @param  string  $extension     config file name extension
118     * @param  bool    $force_compile force all to recompile
119     * @param  int     $time_limit    set maximum execution time
120     * @param  int     $max_errors    set maximum allowed errors
121     * @param  Smarty  $smarty        Smarty instance
122     * @return integer number of config files compiled
123     */
124    public static function compileAllConfig($extension, $force_compile, $time_limit, $max_errors, Smarty $smarty)
125    {
126        // switch off time limit
127        if (function_exists('set_time_limit')) {
128            @set_time_limit($time_limit);
129        }
130        $smarty->force_compile = $force_compile;
131        $_count = 0;
132        $_error_count = 0;
133        // loop over array of template directories
134        foreach ($smarty->getConfigDir() as $_dir) {
135            $_compileDirs = new RecursiveDirectoryIterator($_dir);
136            $_compile = new RecursiveIteratorIterator($_compileDirs);
137            foreach ($_compile as $_fileinfo) {
138                $_file = $_fileinfo->getFilename();
139                if (substr(basename($_fileinfo->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false || strpos($_file, '.git') !== false) continue;
140                if (!substr_compare($_file, $extension, - strlen($extension)) == 0) continue;
141                if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
142                    $_config_file = $_file;
143                } else {
144                    $_config_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file;
145                }
146                echo '<br>', $_dir, '---', $_config_file;
147                flush();
148                $_start_time = microtime(true);
149                try {
150                    $_config = new Smarty_Internal_Config($_config_file, $smarty);
151                    if ($_config->mustCompile()) {
152                        $_config->compileConfigSource();
153                        $_count++;
154                        echo ' compiled in  ', microtime(true) - $_start_time, ' seconds';
155                        flush();
156                    } else {
157                        echo ' is up to date';
158                        flush();
159                    }
160                } catch (Exception $e) {
161                    echo 'Error: ', $e->getMessage(), "<br><br>";
162                    $_error_count++;
163                }
164                if ($max_errors !== null && $_error_count == $max_errors) {
165                    echo '<br><br>too many errors';
166                    exit();
167                }
168            }
169        }
170
171        return $_count;
172    }
173
174    /**
175     * Delete compiled template file
176     *
177     * @param  string  $resource_name template name
178     * @param  string  $compile_id    compile id
179     * @param  integer $exp_time      expiration time
180     * @param  Smarty  $smarty        Smarty instance
181     * @return integer number of template files deleted
182     */
183    public static function clearCompiledTemplate($resource_name, $compile_id, $exp_time, Smarty $smarty)
184    {
185        $_compile_dir = $smarty->getCompileDir();
186        $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
187        $_dir_sep = $smarty->use_sub_dirs ? DS : '^';
188        if (isset($resource_name)) {
189            $_save_stat = $smarty->caching;
190            $smarty->caching = false;
191            $tpl = new $smarty->template_class($resource_name, $smarty);
192            $smarty->caching = $_save_stat;
193
194            // remove from template cache
195            $tpl->source; // have the template registered before unset()
196            if ($smarty->allow_ambiguous_resources) {
197                $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
198            } else {
199                $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
200            }
201            if (isset($_templateId[150])) {
202                $_templateId = sha1($_templateId);
203            }
204            unset($smarty->template_objects[$_templateId]);
205
206            if ($tpl->source->exists) {
207                 $_resource_part_1 = basename(str_replace('^', '/', $tpl->compiled->filepath));
208                 $_resource_part_1_length = strlen($_resource_part_1);
209            } else {
210                return 0;
211            }
212
213            $_resource_part_2 = str_replace('.php','.cache.php',$_resource_part_1);
214            $_resource_part_2_length = strlen($_resource_part_2);
215        }
216        $_dir = $_compile_dir;
217        if ($smarty->use_sub_dirs && isset($_compile_id)) {
218            $_dir .= $_compile_id . $_dir_sep;
219        }
220        if (isset($_compile_id)) {
221            $_compile_id_part = $_compile_dir . $_compile_id . $_dir_sep;
222            $_compile_id_part_length = strlen($_compile_id_part);
223        }
224        $_count = 0;
225        try {
226            $_compileDirs = new RecursiveDirectoryIterator($_dir);
227        // NOTE: UnexpectedValueException thrown for PHP >= 5.3
228        } catch (Exception $e) {
229            return 0;
230        }
231        $_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST);
232        foreach ($_compile as $_file) {
233            if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false || strpos($_file, '.git') !== false) continue;
234
235            $_filepath = (string) $_file;
236
237            if ($_file->isDir()) {
238                if (!$_compile->isDot()) {
239                    // delete folder if empty
240                    @rmdir($_file->getPathname());
241                }
242            } else {
243                $unlink = false;
244                if ((!isset($_compile_id) || (isset($_filepath[$_compile_id_part_length]) && !strncmp($_filepath, $_compile_id_part, $_compile_id_part_length)))
245                    && (!isset($resource_name)
246                        || (isset($_filepath[$_resource_part_1_length])
247                            && substr_compare($_filepath, $_resource_part_1, -$_resource_part_1_length, $_resource_part_1_length) == 0)
248                        || (isset($_filepath[$_resource_part_2_length])
249                            && substr_compare($_filepath, $_resource_part_2, -$_resource_part_2_length, $_resource_part_2_length) == 0))) {
250                    if (isset($exp_time)) {
251                        if (time() - @filemtime($_filepath) >= $exp_time) {
252                            $unlink = true;
253                        }
254                    } else {
255                        $unlink = true;
256                    }
257                }
258
259                if ($unlink && @unlink($_filepath)) {
260                    $_count++;
261                }
262            }
263        }
264        // clear compiled cache
265        Smarty_Resource::$sources = array();
266        Smarty_Resource::$compileds = array();
267
268        return $_count;
269    }
270
271    /**
272     * Return array of tag/attributes of all tags used by an template
273     *
274     * @param  Smarty_Internal_Template $templae template object
275     * @return array                    of tag/attributes
276     */
277    public static function getTags(Smarty_Internal_Template $template)
278    {
279        $template->smarty->get_used_tags = true;
280        $template->compileTemplateSource();
281
282        return $template->used_tags;
283    }
284
285    /**
286     * diagnose Smarty setup
287     *
288     * If $errors is secified, the diagnostic report will be appended to the array, rather than being output.
289     *
290     * @param  Smarty $smarty Smarty instance to test
291     * @param  array  $errors array to push results into rather than outputting them
292     * @return bool   status, true if everything is fine, false else
293     */
294    public static function testInstall(Smarty $smarty, &$errors=null)
295    {
296        $status = true;
297
298        if ($errors === null) {
299            echo "<PRE>\n";
300            echo "Smarty Installation test...\n";
301            echo "Testing template directory...\n";
302        }
303
304        $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
305
306        // test if all registered template_dir are accessible
307        foreach ($smarty->getTemplateDir() as $template_dir) {
308            $_template_dir = $template_dir;
309            $template_dir = realpath($template_dir);
310            // resolve include_path or fail existence
311            if (!$template_dir) {
312                if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_template_dir)) {
313                    // try PHP include_path
314                    if ($_stream_resolve_include_path) {
315                        $template_dir = stream_resolve_include_path($_template_dir);
316                    } else {
317                        $template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir);
318                    }
319
320                    if ($template_dir !== false) {
321                        if ($errors === null) {
322                            echo "$template_dir is OK.\n";
323                        }
324
325                        continue;
326                    } else {
327                        $status = false;
328                        $message = "FAILED: $_template_dir does not exist (and couldn't be found in include_path either)";
329                        if ($errors === null) {
330                            echo $message . ".\n";
331                        } else {
332                            $errors['template_dir'] = $message;
333                        }
334
335                        continue;
336                    }
337                } else {
338                    $status = false;
339                    $message = "FAILED: $_template_dir does not exist";
340                    if ($errors === null) {
341                        echo $message . ".\n";
342                    } else {
343                        $errors['template_dir'] = $message;
344                    }
345
346                    continue;
347                }
348            }
349
350            if (!is_dir($template_dir)) {
351                $status = false;
352                $message = "FAILED: $template_dir is not a directory";
353                if ($errors === null) {
354                    echo $message . ".\n";
355                } else {
356                    $errors['template_dir'] = $message;
357                }
358            } elseif (!is_readable($template_dir)) {
359                $status = false;
360                $message = "FAILED: $template_dir is not readable";
361                if ($errors === null) {
362                    echo $message . ".\n";
363                } else {
364                    $errors['template_dir'] = $message;
365                }
366            } else {
367                if ($errors === null) {
368                    echo "$template_dir is OK.\n";
369                }
370            }
371        }
372
373        if ($errors === null) {
374            echo "Testing compile directory...\n";
375        }
376
377        // test if registered compile_dir is accessible
378        $__compile_dir = $smarty->getCompileDir();
379        $_compile_dir = realpath($__compile_dir);
380        if (!$_compile_dir) {
381            $status = false;
382            $message = "FAILED: {$__compile_dir} does not exist";
383            if ($errors === null) {
384                echo $message . ".\n";
385            } else {
386                $errors['compile_dir'] = $message;
387            }
388        } elseif (!is_dir($_compile_dir)) {
389            $status = false;
390            $message = "FAILED: {$_compile_dir} is not a directory";
391            if ($errors === null) {
392                echo $message . ".\n";
393            } else {
394                $errors['compile_dir'] = $message;
395            }
396        } elseif (!is_readable($_compile_dir)) {
397            $status = false;
398            $message = "FAILED: {$_compile_dir} is not readable";
399            if ($errors === null) {
400                echo $message . ".\n";
401            } else {
402                $errors['compile_dir'] = $message;
403            }
404        } elseif (!is_writable($_compile_dir)) {
405            $status = false;
406            $message = "FAILED: {$_compile_dir} is not writable";
407            if ($errors === null) {
408                echo $message . ".\n";
409            } else {
410                $errors['compile_dir'] = $message;
411            }
412        } else {
413            if ($errors === null) {
414                echo "{$_compile_dir} is OK.\n";
415            }
416        }
417
418        if ($errors === null) {
419            echo "Testing plugins directory...\n";
420        }
421
422        // test if all registered plugins_dir are accessible
423        // and if core plugins directory is still registered
424        $_core_plugins_dir = realpath(dirname(__FILE__) .'/../plugins');
425        $_core_plugins_available = false;
426        foreach ($smarty->getPluginsDir() as $plugin_dir) {
427            $_plugin_dir = $plugin_dir;
428            $plugin_dir = realpath($plugin_dir);
429            // resolve include_path or fail existence
430            if (!$plugin_dir) {
431                if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
432                    // try PHP include_path
433                    if ($_stream_resolve_include_path) {
434                        $plugin_dir = stream_resolve_include_path($_plugin_dir);
435                    } else {
436                        $plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir);
437                    }
438
439                    if ($plugin_dir !== false) {
440                        if ($errors === null) {
441                            echo "$plugin_dir is OK.\n";
442                        }
443
444                        continue;
445                    } else {
446                        $status = false;
447                        $message = "FAILED: $_plugin_dir does not exist (and couldn't be found in include_path either)";
448                        if ($errors === null) {
449                            echo $message . ".\n";
450                        } else {
451                            $errors['plugins_dir'] = $message;
452                        }
453
454                        continue;
455                    }
456                } else {
457                    $status = false;
458                    $message = "FAILED: $_plugin_dir does not exist";
459                    if ($errors === null) {
460                        echo $message . ".\n";
461                    } else {
462                        $errors['plugins_dir'] = $message;
463                    }
464
465                    continue;
466                }
467            }
468
469            if (!is_dir($plugin_dir)) {
470                $status = false;
471                $message = "FAILED: $plugin_dir is not a directory";
472                if ($errors === null) {
473                    echo $message . ".\n";
474                } else {
475                    $errors['plugins_dir'] = $message;
476                }
477            } elseif (!is_readable($plugin_dir)) {
478                $status = false;
479                $message = "FAILED: $plugin_dir is not readable";
480                if ($errors === null) {
481                    echo $message . ".\n";
482                } else {
483                    $errors['plugins_dir'] = $message;
484                }
485            } elseif ($_core_plugins_dir && $_core_plugins_dir == realpath($plugin_dir)) {
486                $_core_plugins_available = true;
487                if ($errors === null) {
488                    echo "$plugin_dir is OK.\n";
489                }
490            } else {
491                if ($errors === null) {
492                    echo "$plugin_dir is OK.\n";
493                }
494            }
495        }
496        if (!$_core_plugins_available) {
497            $status = false;
498            $message = "WARNING: Smarty's own libs/plugins is not available";
499            if ($errors === null) {
500                echo $message . ".\n";
501            } elseif (!isset($errors['plugins_dir'])) {
502                $errors['plugins_dir'] = $message;
503            }
504        }
505
506        if ($errors === null) {
507            echo "Testing cache directory...\n";
508        }
509
510        // test if all registered cache_dir is accessible
511        $__cache_dir = $smarty->getCacheDir();
512        $_cache_dir = realpath($__cache_dir);
513        if (!$_cache_dir) {
514            $status = false;
515            $message = "FAILED: {$__cache_dir} does not exist";
516            if ($errors === null) {
517                echo $message . ".\n";
518            } else {
519                $errors['cache_dir'] = $message;
520            }
521        } elseif (!is_dir($_cache_dir)) {
522            $status = false;
523            $message = "FAILED: {$_cache_dir} is not a directory";
524            if ($errors === null) {
525                echo $message . ".\n";
526            } else {
527                $errors['cache_dir'] = $message;
528            }
529        } elseif (!is_readable($_cache_dir)) {
530            $status = false;
531            $message = "FAILED: {$_cache_dir} is not readable";
532            if ($errors === null) {
533                echo $message . ".\n";
534            } else {
535                $errors['cache_dir'] = $message;
536            }
537        } elseif (!is_writable($_cache_dir)) {
538            $status = false;
539            $message = "FAILED: {$_cache_dir} is not writable";
540            if ($errors === null) {
541                echo $message . ".\n";
542            } else {
543                $errors['cache_dir'] = $message;
544            }
545        } else {
546            if ($errors === null) {
547                echo "{$_cache_dir} is OK.\n";
548            }
549        }
550
551        if ($errors === null) {
552            echo "Testing configs directory...\n";
553        }
554
555        // test if all registered config_dir are accessible
556        foreach ($smarty->getConfigDir() as $config_dir) {
557            $_config_dir = $config_dir;
558            $config_dir = realpath($config_dir);
559            // resolve include_path or fail existence
560            if (!$config_dir) {
561                if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_config_dir)) {
562                    // try PHP include_path
563                    if ($_stream_resolve_include_path) {
564                        $config_dir = stream_resolve_include_path($_config_dir);
565                    } else {
566                        $config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir);
567                    }
568
569                    if ($config_dir !== false) {
570                        if ($errors === null) {
571                            echo "$config_dir is OK.\n";
572                        }
573
574                        continue;
575                    } else {
576                        $status = false;
577                        $message = "FAILED: $_config_dir does not exist (and couldn't be found in include_path either)";
578                        if ($errors === null) {
579                            echo $message . ".\n";
580                        } else {
581                            $errors['config_dir'] = $message;
582                        }
583
584                        continue;
585                    }
586                } else {
587                    $status = false;
588                    $message = "FAILED: $_config_dir does not exist";
589                    if ($errors === null) {
590                        echo $message . ".\n";
591                    } else {
592                        $errors['config_dir'] = $message;
593                    }
594
595                    continue;
596                }
597            }
598
599            if (!is_dir($config_dir)) {
600                $status = false;
601                $message = "FAILED: $config_dir is not a directory";
602                if ($errors === null) {
603                    echo $message . ".\n";
604                } else {
605                    $errors['config_dir'] = $message;
606                }
607            } elseif (!is_readable($config_dir)) {
608                $status = false;
609                $message = "FAILED: $config_dir is not readable";
610                if ($errors === null) {
611                    echo $message . ".\n";
612                } else {
613                    $errors['config_dir'] = $message;
614                }
615            } else {
616                if ($errors === null) {
617                    echo "$config_dir is OK.\n";
618                }
619            }
620        }
621
622        if ($errors === null) {
623            echo "Testing sysplugin files...\n";
624        }
625        // test if sysplugins are available
626        $source = SMARTY_SYSPLUGINS_DIR;
627        if (is_dir($source)) {
628            $expected = array(
629                "smarty_cacheresource.php" => true,
630                "smarty_cacheresource_custom.php" => true,
631                "smarty_cacheresource_keyvaluestore.php" => true,
632                "smarty_config_source.php" => true,
633                "smarty_internal_cacheresource_file.php" => true,
634                "smarty_internal_compile_append.php" => true,
635                "smarty_internal_compile_assign.php" => true,
636                "smarty_internal_compile_block.php" => true,
637                "smarty_internal_compile_break.php" => true,
638                "smarty_internal_compile_call.php" => true,
639                "smarty_internal_compile_capture.php" => true,
640                "smarty_internal_compile_config_load.php" => true,
641                "smarty_internal_compile_continue.php" => true,
642                "smarty_internal_compile_debug.php" => true,
643                "smarty_internal_compile_eval.php" => true,
644                "smarty_internal_compile_extends.php" => true,
645                "smarty_internal_compile_for.php" => true,
646                "smarty_internal_compile_foreach.php" => true,
647                "smarty_internal_compile_function.php" => true,
648                "smarty_internal_compile_if.php" => true,
649                "smarty_internal_compile_include.php" => true,
650                "smarty_internal_compile_include_php.php" => true,
651                "smarty_internal_compile_insert.php" => true,
652                "smarty_internal_compile_ldelim.php" => true,
653                "smarty_internal_compile_nocache.php" => true,
654                "smarty_internal_compile_private_block_plugin.php" => true,
655                "smarty_internal_compile_private_function_plugin.php" => true,
656                "smarty_internal_compile_private_modifier.php" => true,
657                "smarty_internal_compile_private_object_block_function.php" => true,
658                "smarty_internal_compile_private_object_function.php" => true,
659                "smarty_internal_compile_private_print_expression.php" => true,
660                "smarty_internal_compile_private_registered_block.php" => true,
661                "smarty_internal_compile_private_registered_function.php" => true,
662                "smarty_internal_compile_private_special_variable.php" => true,
663                "smarty_internal_compile_rdelim.php" => true,
664                "smarty_internal_compile_section.php" => true,
665                "smarty_internal_compile_setfilter.php" => true,
666                "smarty_internal_compile_while.php" => true,
667                "smarty_internal_compilebase.php" => true,
668                "smarty_internal_config.php" => true,
669                "smarty_internal_config_file_compiler.php" => true,
670                "smarty_internal_configfilelexer.php" => true,
671                "smarty_internal_configfileparser.php" => true,
672                "smarty_internal_data.php" => true,
673                "smarty_internal_debug.php" => true,
674                "smarty_internal_filter_handler.php" => true,
675                "smarty_internal_function_call_handler.php" => true,
676                "smarty_internal_get_include_path.php" => true,
677                "smarty_internal_nocache_insert.php" => true,
678                "smarty_internal_parsetree.php" => true,
679                "smarty_internal_resource_eval.php" => true,
680                "smarty_internal_resource_extends.php" => true,
681                "smarty_internal_resource_file.php" => true,
682                "smarty_internal_resource_registered.php" => true,
683                "smarty_internal_resource_stream.php" => true,
684                "smarty_internal_resource_string.php" => true,
685                "smarty_internal_smartytemplatecompiler.php" => true,
686                "smarty_internal_template.php" => true,
687                "smarty_internal_templatebase.php" => true,
688                "smarty_internal_templatecompilerbase.php" => true,
689                "smarty_internal_templatelexer.php" => true,
690                "smarty_internal_templateparser.php" => true,
691                "smarty_internal_utility.php" => true,
692                "smarty_internal_write_file.php" => true,
693                "smarty_resource.php" => true,
694                "smarty_resource_custom.php" => true,
695                "smarty_resource_recompiled.php" => true,
696                "smarty_resource_uncompiled.php" => true,
697                "smarty_security.php" => true,
698            );
699            $iterator = new DirectoryIterator($source);
700            foreach ($iterator as $file) {
701                if (!$file->isDot()) {
702                    $filename = $file->getFilename();
703                    if (isset($expected[$filename])) {
704                        unset($expected[$filename]);
705                    }
706                }
707            }
708            if ($expected) {
709                $status = false;
710                $message = "FAILED: files missing from libs/sysplugins: ". join(', ', array_keys($expected));
711                if ($errors === null) {
712                    echo $message . ".\n";
713                } else {
714                    $errors['sysplugins'] = $message;
715                }
716            } elseif ($errors === null) {
717                echo "... OK\n";
718            }
719        } else {
720            $status = false;
721            $message = "FAILED: ". SMARTY_SYSPLUGINS_DIR .' is not a directory';
722            if ($errors === null) {
723                echo $message . ".\n";
724            } else {
725                $errors['sysplugins_dir_constant'] = $message;
726            }
727        }
728
729        if ($errors === null) {
730            echo "Testing plugin files...\n";
731        }
732        // test if core plugins are available
733        $source = SMARTY_PLUGINS_DIR;
734        if (is_dir($source)) {
735            $expected = array(
736                "block.textformat.php" => true,
737                "function.counter.php" => true,
738                "function.cycle.php" => true,
739                "function.fetch.php" => true,
740                "function.html_checkboxes.php" => true,
741                "function.html_image.php" => true,
742                "function.html_options.php" => true,
743                "function.html_radios.php" => true,
744                "function.html_select_date.php" => true,
745                "function.html_select_time.php" => true,
746                "function.html_table.php" => true,
747                "function.mailto.php" => true,
748                "function.math.php" => true,
749                "modifier.capitalize.php" => true,
750                "modifier.date_format.php" => true,
751                "modifier.debug_print_var.php" => true,
752                "modifier.escape.php" => true,
753                "modifier.regex_replace.php" => true,
754                "modifier.replace.php" => true,
755                "modifier.spacify.php" => true,
756                "modifier.truncate.php" => true,
757                "modifiercompiler.cat.php" => true,
758                "modifiercompiler.count_characters.php" => true,
759                "modifiercompiler.count_paragraphs.php" => true,
760                "modifiercompiler.count_sentences.php" => true,
761                "modifiercompiler.count_words.php" => true,
762                "modifiercompiler.default.php" => true,
763                "modifiercompiler.escape.php" => true,
764                "modifiercompiler.from_charset.php" => true,
765                "modifiercompiler.indent.php" => true,
766                "modifiercompiler.lower.php" => true,
767                "modifiercompiler.noprint.php" => true,
768                "modifiercompiler.string_format.php" => true,
769                "modifiercompiler.strip.php" => true,
770                "modifiercompiler.strip_tags.php" => true,
771                "modifiercompiler.to_charset.php" => true,
772                "modifiercompiler.unescape.php" => true,
773                "modifiercompiler.upper.php" => true,
774                "modifiercompiler.wordwrap.php" => true,
775                "outputfilter.trimwhitespace.php" => true,
776                "shared.escape_special_chars.php" => true,
777                "shared.literal_compiler_param.php" => true,
778                "shared.make_timestamp.php" => true,
779                "shared.mb_str_replace.php" => true,
780                "shared.mb_unicode.php" => true,
781                "shared.mb_wordwrap.php" => true,
782                "variablefilter.htmlspecialchars.php" => true,
783            );
784            $iterator = new DirectoryIterator($source);
785            foreach ($iterator as $file) {
786                if (!$file->isDot()) {
787                    $filename = $file->getFilename();
788                    if (isset($expected[$filename])) {
789                        unset($expected[$filename]);
790                    }
791                }
792            }
793            if ($expected) {
794                $status = false;
795                $message = "FAILED: files missing from libs/plugins: ". join(', ', array_keys($expected));
796                if ($errors === null) {
797                    echo $message . ".\n";
798                } else {
799                    $errors['plugins'] = $message;
800                }
801            } elseif ($errors === null) {
802                echo "... OK\n";
803            }
804        } else {
805            $status = false;
806            $message = "FAILED: ". SMARTY_PLUGINS_DIR .' is not a directory';
807            if ($errors === null) {
808                echo $message . ".\n";
809            } else {
810                $errors['plugins_dir_constant'] = $message;
811            }
812        }
813
814        if ($errors === null) {
815            echo "Tests complete.\n";
816            echo "</PRE>\n";
817        }
818
819        return $status;
820    }
821
822}
823