1<?php 2 3/** 4 * Project: Smarty: the PHP compiling template engine 5 * File: Smarty.class.php 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-general-subscribe@lists.php.net 24 * 25 * You may contact the authors of Smarty by e-mail at: 26 * monte@ispi.net 27 * andrei@php.net 28 * 29 * Or, write to: 30 * Monte Ohrt 31 * Director of Technology, ispi 32 * 237 S. 70th suite 220 33 * Lincoln, NE 68510 34 * 35 * The latest version of Smarty can be obtained from: 36 * http://smarty.php.net/ 37 * 38 * @link http://smarty.php.net/ 39 * @copyright 2001-2003 ispi of Lincoln, Inc. 40 * @author Monte Ohrt <monte@ispi.net> 41 * @author Andrei Zmievski <andrei@php.net> 42 * @package Smarty 43 * @version 2.6.0 44 */ 45 46/* $Id: Smarty.class.php 198623 2005-10-17 18:37:50Z jeichorn $ */ 47 48/** 49 * DIR_SEP isn't used anymore, but third party apps might 50 */ 51if(!defined('DIR_SEP')) { 52 define('DIR_SEP', DIRECTORY_SEPARATOR); 53} 54 55/** 56 * set SMARTY_DIR to absolute path to Smarty library files. 57 * if not defined, include_path will be used. Sets SMARTY_DIR only if user 58 * application has not already defined it. 59 */ 60 61if (!defined('SMARTY_DIR')) { 62 define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); 63} 64 65define('SMARTY_PHP_PASSTHRU', 0); 66define('SMARTY_PHP_QUOTE', 1); 67define('SMARTY_PHP_REMOVE', 2); 68define('SMARTY_PHP_ALLOW', 3); 69 70/** 71 * @package Smarty 72 */ 73class Smarty 74{ 75 /**#@+ 76 * Smarty Configuration Section 77 */ 78 79 /** 80 * The name of the directory where templates are located. 81 * 82 * @var string 83 */ 84 var $template_dir = 'templates'; 85 86 /** 87 * The directory where compiled templates are located. 88 * 89 * @var string 90 */ 91 var $compile_dir = 'templates_c'; 92 93 /** 94 * The directory where config files are located. 95 * 96 * @var string 97 */ 98 var $config_dir = 'configs'; 99 100 /** 101 * An array of directories searched for plugins. 102 * 103 * @var array 104 */ 105 var $plugins_dir = array('plugins'); 106 107 /** 108 * If debugging is enabled, a debug console window will display 109 * when the page loads (make sure your browser allows unrequested 110 * popup windows) 111 * 112 * @var boolean 113 */ 114 var $debugging = false; 115 116 /** 117 * This is the path to the debug console template. If not set, 118 * the default one will be used. 119 * 120 * @var string 121 */ 122 var $debug_tpl = ''; 123 124 /** 125 * This determines if debugging is enable-able from the browser. 126 * <ul> 127 * <li>NONE => no debugging control allowed</li> 128 * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li> 129 * </ul> 130 * @link http://www.foo.dom/index.php?SMARTY_DEBUG 131 * @var string 132 */ 133 var $debugging_ctrl = 'NONE'; 134 135 /** 136 * This tells Smarty whether to check for recompiling or not. Recompiling 137 * does not need to happen unless a template or config file is changed. 138 * Typically you enable this during development, and disable for 139 * production. 140 * 141 * @var boolean 142 */ 143 var $compile_check = true; 144 145 /** 146 * This forces templates to compile every time. Useful for development 147 * or debugging. 148 * 149 * @var boolean 150 */ 151 var $force_compile = false; 152 153 /** 154 * This enables template caching. 155 * <ul> 156 * <li>0 = no caching</li> 157 * <li>1 = use class cache_lifetime value</li> 158 * <li>2 = use cache_lifetime in cache file</li> 159 * </ul> 160 * @var integer 161 */ 162 var $caching = 0; 163 164 /** 165 * The name of the directory for cache files. 166 * 167 * @var string 168 */ 169 var $cache_dir = 'cache'; 170 171 /** 172 * This is the number of seconds cached content will persist. 173 * <ul> 174 * <li>0 = always regenerate cache</li> 175 * <li>-1 = never expires</li> 176 * </ul> 177 * 178 * @var integer 179 */ 180 var $cache_lifetime = 3600; 181 182 /** 183 * Only used when $caching is enabled. If true, then If-Modified-Since headers 184 * are respected with cached content, and appropriate HTTP headers are sent. 185 * This way repeated hits to a cached page do not send the entire page to the 186 * client every time. 187 * 188 * @var boolean 189 */ 190 var $cache_modified_check = false; 191 192 /** 193 * This determines how Smarty handles "<?php ... ?>" tags in templates. 194 * possible values: 195 * <ul> 196 * <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li> 197 * <li>SMARTY_PHP_QUOTE -> escape tags as entities</li> 198 * <li>SMARTY_PHP_REMOVE -> remove php tags</li> 199 * <li>SMARTY_PHP_ALLOW -> execute php tags</li> 200 * </ul> 201 * 202 * @var integer 203 */ 204 var $php_handling = SMARTY_PHP_PASSTHRU; 205 206 /** 207 * This enables template security. When enabled, many things are restricted 208 * in the templates that normally would go unchecked. This is useful when 209 * untrusted parties are editing templates and you want a reasonable level 210 * of security. (no direct execution of PHP in templates for example) 211 * 212 * @var boolean 213 */ 214 var $security = false; 215 216 /** 217 * This is the list of template directories that are considered secure. This 218 * is used only if {@link $security} is enabled. One directory per array 219 * element. {@link $template_dir} is in this list implicitly. 220 * 221 * @var array 222 */ 223 var $secure_dir = array(); 224 225 /** 226 * These are the security settings for Smarty. They are used only when 227 * {@link $security} is enabled. 228 * 229 * @var array 230 */ 231 var $security_settings = array( 232 'PHP_HANDLING' => false, 233 'IF_FUNCS' => array('array', 'list', 234 'isset', 'empty', 235 'count', 'sizeof', 236 'in_array', 'is_array', 237 'true','false'), 238 'INCLUDE_ANY' => false, 239 'PHP_TAGS' => false, 240 'MODIFIER_FUNCS' => array('count'), 241 'ALLOW_CONSTANTS' => false 242 ); 243 244 /** 245 * This is an array of directories where trusted php scripts reside. 246 * {@link $security} is disabled during their inclusion/execution. 247 * 248 * @var array 249 */ 250 var $trusted_dir = array(); 251 252 /** 253 * The left delimiter used for the template tags. 254 * 255 * @var string 256 */ 257 var $left_delimiter = '{'; 258 259 /** 260 * The right delimiter used for the template tags. 261 * 262 * @var string 263 */ 264 var $right_delimiter = '}'; 265 266 /** 267 * The order in which request variables are registered, similar to 268 * variables_order in php.ini E = Environment, G = GET, P = POST, 269 * C = Cookies, S = Server 270 * 271 * @var string 272 */ 273 var $request_vars_order = "EGPCS"; 274 275 /** 276 * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false) 277 * are uses as request-vars or $_*[]-vars. note: if 278 * request_use_auto_globals is true, then $request_vars_order has 279 * no effect, but the php-ini-value "gpc_order" 280 * 281 * @var boolean 282 */ 283 var $request_use_auto_globals = false; 284 285 /** 286 * Set this if you want different sets of compiled files for the same 287 * templates. This is useful for things like different languages. 288 * Instead of creating separate sets of templates per language, you 289 * set different compile_ids like 'en' and 'de'. 290 * 291 * @var string 292 */ 293 var $compile_id = null; 294 295 /** 296 * This tells Smarty whether or not to use sub dirs in the cache/ and 297 * templates_c/ directories. sub directories better organized, but 298 * may not work well with PHP safe mode enabled. 299 * 300 * @var boolean 301 * 302 */ 303 var $use_sub_dirs = true; 304 305 /** 306 * This is a list of the modifiers to apply to all template variables. 307 * Put each modifier in a separate array element in the order you want 308 * them applied. example: <code>array('escape:"htmlall"');</code> 309 * 310 * @var array 311 */ 312 var $default_modifiers = array(); 313 314 /** 315 * This is the resource type to be used when not specified 316 * at the beginning of the resource path. examples: 317 * $smarty->display('file:index.tpl'); 318 * $smarty->display('db:index.tpl'); 319 * $smarty->display('index.tpl'); // will use default resource type 320 * {include file="file:index.tpl"} 321 * {include file="db:index.tpl"} 322 * {include file="index.tpl"} {* will use default resource type *} 323 * 324 * @var array 325 */ 326 var $default_resource_type = 'file'; 327 328 /** 329 * The function used for cache file handling. If not set, built-in caching is used. 330 * 331 * @var null|string function name 332 */ 333 var $cache_handler_func = null; 334 335 /** 336 * These are the variables from the globals array that are 337 * assigned to all templates automatically. This isn't really 338 * necessary any more, you can use the $smarty var to access them 339 * directly. 340 * 341 * @var array 342 */ 343 var $global_assign = array('HTTP_SERVER_VARS' => array('SCRIPT_NAME')); 344 345 /** 346 * The value of "undefined". Leave it alone :-) 347 * 348 * @var null 349 */ 350 var $undefined = null; 351 352 /** 353 * This indicates which filters are automatically loaded into Smarty. 354 * 355 * @var array array of filter names 356 */ 357 var $autoload_filters = array(); 358 359 /**#@+ 360 * @var boolean 361 */ 362 /** 363 * This tells if config file vars of the same name overwrite each other or not. 364 * if disabled, same name variables are accumulated in an array. 365 */ 366 var $config_overwrite = true; 367 368 /** 369 * This tells whether or not to automatically booleanize config file variables. 370 * If enabled, then the strings "on", "true", and "yes" are treated as boolean 371 * true, and "off", "false" and "no" are treated as boolean false. 372 */ 373 var $config_booleanize = true; 374 375 /** 376 * This tells whether hidden sections [.foobar] are readable from the 377 * tempalates or not. Normally you would never allow this since that is 378 * the point behind hidden sections: the application can access them, but 379 * the templates cannot. 380 */ 381 var $config_read_hidden = false; 382 383 /** 384 * This tells whether or not automatically fix newlines in config files. 385 * It basically converts \r (mac) or \r\n (dos) to \n 386 */ 387 var $config_fix_newlines = true; 388 /**#@-*/ 389 390 /** 391 * If a template cannot be found, this PHP function will be executed. 392 * Useful for creating templates on-the-fly or other special action. 393 * 394 * @var string function name 395 */ 396 var $default_template_handler_func = ''; 397 398 /** 399 * The file that contains the compiler class. This can a full 400 * pathname, or relative to the php_include path. 401 * 402 * @var string 403 */ 404 var $compiler_file = 'Smarty_Compiler.class.php'; 405 406 /** 407 * The class used for compiling templates. 408 * 409 * @var string 410 */ 411 var $compiler_class = 'Smarty_Compiler'; 412 413 /** 414 * The class used to load config vars. 415 * 416 * @var string 417 */ 418 var $config_class = 'Config_File'; 419 420/**#@+ 421 * END Smarty Configuration Section 422 * There should be no need to touch anything below this line. 423 * @access private 424 */ 425 /** 426 * error messages. true/false 427 * 428 * @var boolean 429 */ 430 var $_error_msg = false; 431 432 /** 433 * where assigned template vars are kept 434 * 435 * @var array 436 */ 437 var $_tpl_vars = array(); 438 439 /** 440 * stores run-time $smarty.* vars 441 * 442 * @var null|array 443 */ 444 var $_smarty_vars = null; 445 446 /** 447 * keeps track of sections 448 * 449 * @var array 450 */ 451 var $_sections = array(); 452 453 /** 454 * keeps track of foreach blocks 455 * 456 * @var array 457 */ 458 var $_foreach = array(); 459 460 /** 461 * keeps track of tag hierarchy 462 * 463 * @var array 464 */ 465 var $_tag_stack = array(); 466 467 /** 468 * configuration object 469 * 470 * @var Config_file 471 */ 472 var $_conf_obj = null; 473 474 /** 475 * loaded configuration settings 476 * 477 * @var array 478 */ 479 var $_config = array(array('vars' => array(), 'files' => array())); 480 481 /** 482 * md5 checksum of the string 'Smarty' 483 * 484 * @var string 485 */ 486 var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; 487 488 /** 489 * Smarty version number 490 * 491 * @var string 492 */ 493 var $_version = '2.6.0'; 494 495 /** 496 * current template inclusion depth 497 * 498 * @var integer 499 */ 500 var $_inclusion_depth = 0; 501 502 /** 503 * for different compiled templates 504 * 505 * @var string 506 */ 507 var $_compile_id = null; 508 509 /** 510 * text in URL to enable debug mode 511 * 512 * @var string 513 */ 514 var $_smarty_debug_id = 'SMARTY_DEBUG'; 515 516 /** 517 * debugging information for debug console 518 * 519 * @var array 520 */ 521 var $_smarty_debug_info = array(); 522 523 /** 524 * info that makes up a cache file 525 * 526 * @var array 527 */ 528 var $_cache_info = array(); 529 530 /** 531 * default file permissions 532 * 533 * @var integer 534 */ 535 var $_file_perms = 0644; 536 537 /** 538 * default dir permissions 539 * 540 * @var integer 541 */ 542 var $_dir_perms = 0771; 543 544 /** 545 * registered objects 546 * 547 * @var array 548 */ 549 var $_reg_objects = array(); 550 551 /** 552 * table keeping track of plugins 553 * 554 * @var array 555 */ 556 var $_plugins = array( 557 'modifier' => array(), 558 'function' => array(), 559 'block' => array(), 560 'compiler' => array(), 561 'prefilter' => array(), 562 'postfilter' => array(), 563 'outputfilter' => array(), 564 'resource' => array(), 565 'insert' => array()); 566 567 568 /** 569 * cache serials 570 * 571 * @var array 572 */ 573 var $_cache_serials = array(); 574 575 /** 576 * name of optional cache include file 577 * 578 * @var string 579 */ 580 var $_cache_include = null; 581 582 /** 583 * indicate if the current code is used in a compiled 584 * include 585 * 586 * @var string 587 */ 588 var $_cache_including = false; 589 590 /**#@-*/ 591 /** 592 * The class constructor. 593 * 594 * @uses $global_assign uses {@link assign()} to assign each corresponding 595 * value from $GLOBALS to the template vars 596 */ 597 function Smarty() 598 { 599 foreach ($this->global_assign as $key => $var_name) { 600 if (is_array($var_name)) { 601 foreach ($var_name as $var) { 602 if (isset($GLOBALS[$key][$var])) { 603 $this->assign($var, $GLOBALS[$key][$var]); 604 } else { 605 $this->assign($var, $this->undefined); 606 } 607 } 608 } else { 609 if (isset($GLOBALS[$var_name])) { 610 $this->assign($var_name, $GLOBALS[$var_name]); 611 } else { 612 $this->assign($var_name, $this->undefined); 613 } 614 } 615 } 616 } 617 618 619 /** 620 * assigns values to template variables 621 * 622 * @param array|string $tpl_var the template variable name(s) 623 * @param mixed $value the value to assign 624 */ 625 function assign($tpl_var, $value = null) 626 { 627 if (is_array($tpl_var)){ 628 foreach ($tpl_var as $key => $val) { 629 if ($key != '') { 630 $this->_tpl_vars[$key] = $val; 631 } 632 } 633 } else { 634 if ($tpl_var != '') 635 $this->_tpl_vars[$tpl_var] = $value; 636 } 637 } 638 639 /** 640 * assigns values to template variables by reference 641 * 642 * @param string $tpl_var the template variable name 643 * @param mixed $value the referenced value to assign 644 */ 645 function assign_by_ref($tpl_var, &$value) 646 { 647 if ($tpl_var != '') 648 $this->_tpl_vars[$tpl_var] = &$value; 649 } 650 651 /** 652 * appends values to template variables 653 * 654 * @param array|string $tpl_var the template variable name(s) 655 * @param mixed $value the value to append 656 */ 657 function append($tpl_var, $value=null, $merge=false) 658 { 659 if (is_array($tpl_var)) { 660 // $tpl_var is an array, ignore $value 661 foreach ($tpl_var as $_key => $_val) { 662 if ($_key != '') { 663 if(!@is_array($this->_tpl_vars[$_key])) { 664 settype($this->_tpl_vars[$_key],'array'); 665 } 666 if($merge && is_array($_val)) { 667 foreach($_val as $_mkey => $_mval) { 668 $this->_tpl_vars[$_key][$_mkey] = $_mval; 669 } 670 } else { 671 $this->_tpl_vars[$_key][] = $_val; 672 } 673 } 674 } 675 } else { 676 if ($tpl_var != '' && isset($value)) { 677 if(!@is_array($this->_tpl_vars[$tpl_var])) { 678 settype($this->_tpl_vars[$tpl_var],'array'); 679 } 680 if($merge && is_array($value)) { 681 foreach($value as $_mkey => $_mval) { 682 $this->_tpl_vars[$tpl_var][$_mkey] = $_mval; 683 } 684 } else { 685 $this->_tpl_vars[$tpl_var][] = $value; 686 } 687 } 688 } 689 } 690 691 /** 692 * appends values to template variables by reference 693 * 694 * @param string $tpl_var the template variable name 695 * @param mixed $value the referenced value to append 696 */ 697 function append_by_ref($tpl_var, &$value, $merge=false) 698 { 699 if ($tpl_var != '' && isset($value)) { 700 if(!@is_array($this->_tpl_vars[$tpl_var])) { 701 settype($this->_tpl_vars[$tpl_var],'array'); 702 } 703 if ($merge && is_array($value)) { 704 foreach($value as $_key => $_val) { 705 $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key]; 706 } 707 } else { 708 $this->_tpl_vars[$tpl_var][] = &$value; 709 } 710 } 711 } 712 713 714 /** 715 * clear the given assigned template variable. 716 * 717 * @param string $tpl_var the template variable to clear 718 */ 719 function clear_assign($tpl_var) 720 { 721 if (is_array($tpl_var)) 722 foreach ($tpl_var as $curr_var) 723 unset($this->_tpl_vars[$curr_var]); 724 else 725 unset($this->_tpl_vars[$tpl_var]); 726 } 727 728 729 /** 730 * Registers custom function to be used in templates 731 * 732 * @param string $function the name of the template function 733 * @param string $function_impl the name of the PHP function to register 734 */ 735 function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null) 736 { 737 $this->_plugins['function'][$function] = 738 array($function_impl, null, null, false, $cacheable, $cache_attrs); 739 740 } 741 742 /** 743 * Unregisters custom function 744 * 745 * @param string $function name of template function 746 */ 747 function unregister_function($function) 748 { 749 unset($this->_plugins['function'][$function]); 750 } 751 752 /** 753 * Registers object to be used in templates 754 * 755 * @param string $object name of template object 756 * @param object &$object_impl the referenced PHP object to register 757 * @param null|array $allowed list of allowed methods (empty = all) 758 * @param boolean $smarty_args smarty argument format, else traditional 759 * @param null|array $block_functs list of methods that are block format 760 */ 761 function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) 762 { 763 settype($allowed, 'array'); 764 settype($smarty_args, 'boolean'); 765 $this->_reg_objects[$object] = 766 array(&$object_impl, $allowed, $smarty_args, $block_methods); 767 } 768 769 /** 770 * Unregisters object 771 * 772 * @param string $object name of template object 773 */ 774 function unregister_object($object) 775 { 776 unset($this->_reg_objects[$object]); 777 } 778 779 780 /** 781 * Registers block function to be used in templates 782 * 783 * @param string $block name of template block 784 * @param string $block_impl PHP function to register 785 */ 786 function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null) 787 { 788 $this->_plugins['block'][$block] = 789 array($block_impl, null, null, false, $cacheable, $cache_attrs); 790 } 791 792 /** 793 * Unregisters block function 794 * 795 * @param string $block name of template function 796 */ 797 function unregister_block($block) 798 { 799 unset($this->_plugins['block'][$block]); 800 } 801 802 /** 803 * Registers compiler function 804 * 805 * @param string $function name of template function 806 * @param string $function_impl name of PHP function to register 807 */ 808 function register_compiler_function($function, $function_impl, $cacheable=true) 809 { 810 $this->_plugins['compiler'][$function] = 811 array($function_impl, null, null, false, $cacheable); 812 } 813 814 /** 815 * Unregisters compiler function 816 * 817 * @param string $function name of template function 818 */ 819 function unregister_compiler_function($function) 820 { 821 unset($this->_plugins['compiler'][$function]); 822 } 823 824 /** 825 * Registers modifier to be used in templates 826 * 827 * @param string $modifier name of template modifier 828 * @param string $modifier_impl name of PHP function to register 829 */ 830 function register_modifier($modifier, $modifier_impl) 831 { 832 $this->_plugins['modifier'][$modifier] = 833 array($modifier_impl, null, null, false); 834 } 835 836 /** 837 * Unregisters modifier 838 * 839 * @param string $modifier name of template modifier 840 */ 841 function unregister_modifier($modifier) 842 { 843 unset($this->_plugins['modifier'][$modifier]); 844 } 845 846 /** 847 * Registers a resource to fetch a template 848 * 849 * @param string $type name of resource 850 * @param array $functions array of functions to handle resource 851 */ 852 function register_resource($type, $functions) 853 { 854 if (count($functions)==4) { 855 $this->_plugins['resource'][$type] = 856 array($functions, false); 857 858 } elseif (count($functions)==5) { 859 $this->_plugins['resource'][$type] = 860 array(array(array(&$functions[0], $functions[1]) 861 ,array(&$functions[0], $functions[2]) 862 ,array(&$functions[0], $functions[3]) 863 ,array(&$functions[0], $functions[4])) 864 ,false); 865 866 } else { 867 $this->trigger_error("malformed function-list for '$type' in register_resource"); 868 869 } 870 } 871 872 /** 873 * Unregisters a resource 874 * 875 * @param string $type name of resource 876 */ 877 function unregister_resource($type) 878 { 879 unset($this->_plugins['resource'][$type]); 880 } 881 882 /** 883 * Registers a prefilter function to apply 884 * to a template before compiling 885 * 886 * @param string $function name of PHP function to register 887 */ 888 function register_prefilter($function) 889 { 890 $_name = (is_array($function)) ? $function[1] : $function; 891 $this->_plugins['prefilter'][$_name] 892 = array($function, null, null, false); 893 } 894 895 /** 896 * Unregisters a prefilter function 897 * 898 * @param string $function name of PHP function 899 */ 900 function unregister_prefilter($function) 901 { 902 unset($this->_plugins['prefilter'][$function]); 903 } 904 905 /** 906 * Registers a postfilter function to apply 907 * to a compiled template after compilation 908 * 909 * @param string $function name of PHP function to register 910 */ 911 function register_postfilter($function) 912 { 913 $_name = (is_array($function)) ? $function[1] : $function; 914 $this->_plugins['postfilter'][$_name] 915 = array($function, null, null, false); 916 } 917 918 /** 919 * Unregisters a postfilter function 920 * 921 * @param string $function name of PHP function 922 */ 923 function unregister_postfilter($function) 924 { 925 unset($this->_plugins['postfilter'][$function]); 926 } 927 928 /** 929 * Registers an output filter function to apply 930 * to a template output 931 * 932 * @param string $function name of PHP function 933 */ 934 function register_outputfilter($function) 935 { 936 $_name = (is_array($function)) ? $function[1] : $function; 937 $this->_plugins['outputfilter'][$_name] 938 = array($function, null, null, false); 939 } 940 941 /** 942 * Unregisters an outputfilter function 943 * 944 * @param string $function name of PHP function 945 */ 946 function unregister_outputfilter($function) 947 { 948 unset($this->_plugins['outputfilter'][$function]); 949 } 950 951 /** 952 * load a filter of specified type and name 953 * 954 * @param string $type filter type 955 * @param string $name filter name 956 */ 957 function load_filter($type, $name) 958 { 959 switch ($type) { 960 case 'output': 961 $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false))); 962 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php'); 963 smarty_core_load_plugins($_params, $this); 964 break; 965 966 case 'pre': 967 case 'post': 968 if (!isset($this->_plugins[$type . 'filter'][$name])) 969 $this->_plugins[$type . 'filter'][$name] = false; 970 break; 971 } 972 } 973 974 /** 975 * clear cached content for the given template and cache id 976 * 977 * @param string $tpl_file name of template file 978 * @param string $cache_id name of cache_id 979 * @param string $compile_id name of compile_id 980 * @param string $exp_time expiration time 981 * @return boolean 982 */ 983 function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) 984 { 985 986 if (!isset($compile_id)) 987 $compile_id = $this->compile_id; 988 989 if (!isset($tpl_file)) 990 $compile_id = null; 991 992 $_auto_id = $this->_get_auto_id($cache_id, $compile_id); 993 994 if (!empty($this->cache_handler_func)) { 995 return call_user_func_array($this->cache_handler_func, 996 array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time)); 997 } else { 998 $_params = array('auto_base' => $this->cache_dir, 999 'auto_source' => $tpl_file, 1000 'auto_id' => $_auto_id, 1001 'exp_time' => $exp_time); 1002 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rm_auto.php'); 1003 return smarty_core_rm_auto($_params, $this); 1004 } 1005 1006 } 1007 1008 1009 /** 1010 * clear the entire contents of cache (all templates) 1011 * 1012 * @param string $exp_time expire time 1013 * @return boolean results of {@link smarty_core_rm_auto()} 1014 */ 1015 function clear_all_cache($exp_time = null) 1016 { 1017 if (!empty($this->cache_handler_func)) { 1018 $dummy = null; 1019 call_user_func_array($this->cache_handler_func, 1020 array('clear', &$this, &$dummy, null, null, null, $exp_time)); 1021 } else { 1022 $_params = array('auto_base' => $this->cache_dir, 1023 'auto_source' => null, 1024 'auto_id' => null, 1025 'exp_time' => $exp_time); 1026 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rm_auto.php'); 1027 return smarty_core_rm_auto($_params, $this); 1028 } 1029 } 1030 1031 1032 /** 1033 * test to see if valid cache exists for this template 1034 * 1035 * @param string $tpl_file name of template file 1036 * @param string $cache_id 1037 * @param string $compile_id 1038 * @return string|false results of {@link _read_cache_file()} 1039 */ 1040 function is_cached($tpl_file, $cache_id = null, $compile_id = null) 1041 { 1042 if (!$this->caching) 1043 return false; 1044 1045 if (!isset($compile_id)) 1046 $compile_id = $this->compile_id; 1047 1048 $_params = array( 1049 'tpl_file' => $tpl_file, 1050 'cache_id' => $cache_id, 1051 'compile_id' => $compile_id 1052 ); 1053 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.read_cache_file.php'); 1054 return smarty_core_read_cache_file($_params, $this); 1055 } 1056 1057 1058 /** 1059 * clear all the assigned template variables. 1060 * 1061 */ 1062 function clear_all_assign() 1063 { 1064 $this->_tpl_vars = array(); 1065 } 1066 1067 /** 1068 * clears compiled version of specified template resource, 1069 * or all compiled template files if one is not specified. 1070 * This function is for advanced use only, not normally needed. 1071 * 1072 * @param string $tpl_file 1073 * @param string $compile_id 1074 * @param string $exp_time 1075 * @return boolean results of {@link smarty_core_rm_auto()} 1076 */ 1077 function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) 1078 { 1079 if (!isset($compile_id)) { 1080 $compile_id = $this->compile_id; 1081 } 1082 $_params = array('auto_base' => $this->compile_dir, 1083 'auto_source' => $tpl_file, 1084 'auto_id' => $compile_id, 1085 'exp_time' => $exp_time, 1086 'extensions' => array('.inc', '.php')); 1087 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rm_auto.php'); 1088 return smarty_core_rm_auto($_params, $this); 1089 } 1090 1091 /** 1092 * Checks whether requested template exists. 1093 * 1094 * @param string $tpl_file 1095 * @return boolean 1096 */ 1097 function template_exists($tpl_file) 1098 { 1099 $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false); 1100 return $this->_fetch_resource_info($_params); 1101 } 1102 1103 /** 1104 * Returns an array containing template variables 1105 * 1106 * @param string $name 1107 * @param string $type 1108 * @return array 1109 */ 1110 function &get_template_vars($name=null) 1111 { 1112 if(!isset($name)) { 1113 return $this->_tpl_vars; 1114 } 1115 if(isset($this->_tpl_vars[$name])) { 1116 return $this->_tpl_vars[$name]; 1117 } 1118 } 1119 1120 /** 1121 * Returns an array containing config variables 1122 * 1123 * @param string $name 1124 * @param string $type 1125 * @return array 1126 */ 1127 function &get_config_vars($name=null) 1128 { 1129 if(!isset($name) && is_array($this->_config[0])) { 1130 return $this->_config[0]['vars']; 1131 } else if(isset($this->_config[0]['vars'][$name])) { 1132 return $this->_config[0]['vars'][$name]; 1133 } 1134 } 1135 1136 /** 1137 * trigger Smarty error 1138 * 1139 * @param string $error_msg 1140 * @param integer $error_type 1141 */ 1142 function trigger_error($error_msg, $error_type = E_USER_WARNING) 1143 { 1144 trigger_error("Smarty error: $error_msg", $error_type); 1145 } 1146 1147 1148 /** 1149 * executes & displays the template results 1150 * 1151 * @param string $resource_name 1152 * @param string $cache_id 1153 * @param string $compile_id 1154 */ 1155 function display($resource_name, $cache_id = null, $compile_id = null) 1156 { 1157 $this->fetch($resource_name, $cache_id, $compile_id, true); 1158 } 1159 1160 /** 1161 * executes & returns or displays the template results 1162 * 1163 * @param string $resource_name 1164 * @param string $cache_id 1165 * @param string $compile_id 1166 * @param boolean $display 1167 */ 1168 function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false) 1169 { 1170 static $_cache_info = array(); 1171 1172 $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(error_reporting() & ~E_NOTICE); 1173 1174 if (!$this->debugging && $this->debugging_ctrl == 'URL' 1175 && @strstr($GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'], $this->_smarty_debug_id)) { 1176 // enable debugging from URL 1177 $this->debugging = true; 1178 } 1179 1180 if ($this->debugging) { 1181 // capture time for debugging info 1182 $_params = array(); 1183 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); 1184 $_debug_start_time = smarty_core_get_microtime($_params, $this); 1185 $this->_smarty_debug_info[] = array('type' => 'template', 1186 'filename' => $resource_name, 1187 'depth' => 0); 1188 $_included_tpls_idx = count($this->_smarty_debug_info) - 1; 1189 } 1190 1191 if (!isset($compile_id)) { 1192 $compile_id = $this->compile_id; 1193 } 1194 1195 $this->_compile_id = $compile_id; 1196 $this->_inclusion_depth = 0; 1197 1198 if ($this->caching) { 1199 // save old cache_info, initialize cache_info 1200 array_push($_cache_info, $this->_cache_info); 1201 $this->_cache_info = array(); 1202 $_params = array( 1203 'tpl_file' => $resource_name, 1204 'cache_id' => $cache_id, 1205 'compile_id' => $compile_id, 1206 'results' => null 1207 ); 1208 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.read_cache_file.php'); 1209 if (smarty_core_read_cache_file($_params, $this)) { 1210 $_smarty_results = $_params['results']; 1211 if (@count($this->_cache_info['insert_tags'])) { 1212 $_params = array('plugins' => $this->_cache_info['insert_tags']); 1213 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php'); 1214 smarty_core_load_plugins($_params, $this); 1215 $_params = array('results' => $_smarty_results); 1216 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.process_cached_inserts.php'); 1217 $_smarty_results = smarty_core_process_cached_inserts($_params, $this); 1218 } 1219 if (@count($this->_cache_info['cache_serials'])) { 1220 $_params = array('results' => $_smarty_results); 1221 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.process_compiled_include.php'); 1222 $_smarty_results = smarty_core_process_compiled_include($_params, $this); 1223 } 1224 1225 1226 if ($display) { 1227 if ($this->debugging) 1228 { 1229 // capture time for debugging info 1230 $_params = array(); 1231 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); 1232 $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time; 1233 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.display_debug_console.php'); 1234 $_smarty_results .= smarty_core_display_debug_console($_params, $this); 1235 } 1236 if ($this->cache_modified_check) { 1237 $_last_modified_date = @substr($GLOBALS['HTTP_SERVER_VARS']['HTTP_IF_MODIFIED_SINCE'], 0, strpos($GLOBALS['HTTP_SERVER_VARS']['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); 1238 $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; 1239 if (@count($this->_cache_info['insert_tags']) == 0 1240 && !$this->_cache_serials 1241 && $_gmt_mtime == $_last_modified_date) { 1242 if (php_sapi_name()=='cgi') 1243 header("Status: 304 Not Modified"); 1244 else 1245 header("HTTP/1.1 304 Not Modified"); 1246 1247 } else { 1248 header("Last-Modified: ".$_gmt_mtime); 1249 echo $_smarty_results; 1250 } 1251 } else { 1252 echo $_smarty_results; 1253 } 1254 error_reporting($_smarty_old_error_level); 1255 // restore initial cache_info 1256 $this->_cache_info = array_pop($_cache_info); 1257 return true; 1258 } else { 1259 error_reporting($_smarty_old_error_level); 1260 // restore initial cache_info 1261 $this->_cache_info = array_pop($_cache_info); 1262 return $_smarty_results; 1263 } 1264 } else { 1265 $this->_cache_info['template'][$resource_name] = true; 1266 if ($this->cache_modified_check) { 1267 header("Last-Modified: ".gmdate('D, d M Y H:i:s', time()).' GMT'); 1268 } 1269 } 1270 } 1271 1272 // load filters that are marked as autoload 1273 if (count($this->autoload_filters)) { 1274 foreach ($this->autoload_filters as $_filter_type => $_filters) { 1275 foreach ($_filters as $_filter) { 1276 $this->load_filter($_filter_type, $_filter); 1277 } 1278 } 1279 } 1280 1281 $_smarty_compile_path = $this->_get_compile_path($resource_name); 1282 1283 // if we just need to display the results, don't perform output 1284 // buffering - for speed 1285 $_cache_including = $this->_cache_including; 1286 $this->_cache_including = false; 1287 if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) { 1288 if ($this->_is_compiled($resource_name, $_smarty_compile_path) 1289 || $this->_compile_resource($resource_name, $_smarty_compile_path)) 1290 { 1291 include($_smarty_compile_path); 1292 } 1293 } else { 1294 ob_start(); 1295 if ($this->_is_compiled($resource_name, $_smarty_compile_path) 1296 || $this->_compile_resource($resource_name, $_smarty_compile_path)) 1297 { 1298 include($_smarty_compile_path); 1299 } 1300 $_smarty_results = ob_get_contents(); 1301 ob_end_clean(); 1302 1303 foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) { 1304 $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this)); 1305 } 1306 } 1307 1308 if ($this->caching) { 1309 $_params = array('tpl_file' => $resource_name, 1310 'cache_id' => $cache_id, 1311 'compile_id' => $compile_id, 1312 'results' => $_smarty_results); 1313 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_cache_file.php'); 1314 smarty_core_write_cache_file($_params, $this); 1315 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.process_cached_inserts.php'); 1316 $_smarty_results = smarty_core_process_cached_inserts($_params, $this); 1317 1318 if ($this->_cache_serials) { 1319 // strip nocache-tags from output 1320 $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s' 1321 ,'' 1322 ,$_smarty_results); 1323 } 1324 // restore initial cache_info 1325 $this->_cache_info = array_pop($_cache_info); 1326 } 1327 $this->_cache_including = $_cache_including; 1328 1329 if ($display) { 1330 if (isset($_smarty_results)) { echo $_smarty_results; } 1331 if ($this->debugging) { 1332 // capture time for debugging info 1333 $_params = array(); 1334 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); 1335 $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time); 1336 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.display_debug_console.php'); 1337 echo smarty_core_display_debug_console($_params, $this); 1338 } 1339 error_reporting($_smarty_old_error_level); 1340 return; 1341 } else { 1342 error_reporting($_smarty_old_error_level); 1343 if (isset($_smarty_results)) { return $_smarty_results; } 1344 } 1345 } 1346 1347 /** 1348 * load configuration values 1349 * 1350 * @param string $file 1351 * @param string $section 1352 * @param string $scope 1353 */ 1354 function config_load($file, $section = null, $scope = 'global') 1355 { 1356 require_once($this->_get_plugin_filepath('function', 'config_load')); 1357 smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this); 1358 } 1359 1360 /** 1361 * return a reference to a registered object 1362 * 1363 * @param string $name 1364 * @return object 1365 */ 1366 function &get_registered_object($name) { 1367 if (!isset($this->_reg_objects[$name])) 1368 $this->_trigger_fatal_error("'$name' is not a registered object"); 1369 1370 if (!is_object($this->_reg_objects[$name][0])) 1371 $this->_trigger_fatal_error("registered '$name' is not an object"); 1372 1373 return $this->_reg_objects[$name][0]; 1374 } 1375 1376 /** 1377 * clear configuration values 1378 * 1379 * @param string $var 1380 */ 1381 function clear_config($var = null) 1382 { 1383 if(!isset($var)) { 1384 // clear all values 1385 $this->_config = array(array('vars' => array(), 1386 'files' => array())); 1387 } else { 1388 unset($this->_config[0]['vars'][$var]); 1389 } 1390 } 1391 1392 /** 1393 * get filepath of requested plugin 1394 * 1395 * @param string $type 1396 * @param string $name 1397 * @return string|false 1398 */ 1399 function _get_plugin_filepath($type, $name) 1400 { 1401 $_params = array('type' => $type, 'name' => $name); 1402 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.assemble_plugin_filepath.php'); 1403 return smarty_core_assemble_plugin_filepath($_params, $this); 1404 } 1405 1406 /** 1407 * test if resource needs compiling 1408 * 1409 * @param string $resource_name 1410 * @param string $compile_path 1411 * @return boolean 1412 */ 1413 function _is_compiled($resource_name, $compile_path) 1414 { 1415 if (!$this->force_compile && file_exists($compile_path)) { 1416 if (!$this->compile_check) { 1417 // no need to check compiled file 1418 return true; 1419 } else { 1420 // get file source and timestamp 1421 $_params = array('resource_name' => $resource_name, 'get_source'=>false); 1422 if (!$this->_fetch_resource_info($_params, $this)) { 1423 return false; 1424 } 1425 if ($_params['resource_timestamp'] <= filemtime($compile_path)) { 1426 // template not expired, no recompile 1427 return true; 1428 } else { 1429 // compile template 1430 return false; 1431 } 1432 } 1433 } else { 1434 // compiled template does not exist, or forced compile 1435 return false; 1436 } 1437 } 1438 1439 /** 1440 * compile the template 1441 * 1442 * @param string $resource_name 1443 * @param string $compile_path 1444 * @return boolean 1445 */ 1446 function _compile_resource($resource_name, $compile_path) 1447 { 1448 1449 $_params = array('resource_name' => $resource_name); 1450 if (!$this->_fetch_resource_info($_params)) { 1451 return false; 1452 } 1453 1454 $_source_content = $_params['source_content']; 1455 $_resource_timestamp = $_params['resource_timestamp']; 1456 $_cache_include = substr($compile_path, 0, -4).'.inc'; 1457 1458 if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) { 1459 // if a _cache_serial was set, we also have to write an include-file: 1460 if ($this->_cache_include_info) { 1461 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_compiled_include.php'); 1462 smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content)), $this); 1463 } 1464 1465 $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content, 'resource_timestamp' => $_resource_timestamp); 1466 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_compiled_resource.php'); 1467 smarty_core_write_compiled_resource($_params, $this); 1468 1469 return true; 1470 } else { 1471 $this->trigger_error($smarty_compiler->_error_msg); 1472 return false; 1473 } 1474 1475 } 1476 1477 /** 1478 * compile the given source 1479 * 1480 * @param string $resource_name 1481 * @param string $source_content 1482 * @param string $compiled_content 1483 * @return boolean 1484 */ 1485 function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null) 1486 { 1487 if (file_exists(SMARTY_DIR . $this->compiler_file)) { 1488 require_once(SMARTY_DIR . $this->compiler_file); 1489 } else { 1490 // use include_path 1491 require_once($this->compiler_file); 1492 } 1493 1494 1495 $smarty_compiler = new $this->compiler_class; 1496 1497 $smarty_compiler->template_dir = $this->template_dir; 1498 $smarty_compiler->compile_dir = $this->compile_dir; 1499 $smarty_compiler->plugins_dir = $this->plugins_dir; 1500 $smarty_compiler->config_dir = $this->config_dir; 1501 $smarty_compiler->force_compile = $this->force_compile; 1502 $smarty_compiler->caching = $this->caching; 1503 $smarty_compiler->php_handling = $this->php_handling; 1504 $smarty_compiler->left_delimiter = $this->left_delimiter; 1505 $smarty_compiler->right_delimiter = $this->right_delimiter; 1506 $smarty_compiler->_version = $this->_version; 1507 $smarty_compiler->security = $this->security; 1508 $smarty_compiler->secure_dir = $this->secure_dir; 1509 $smarty_compiler->security_settings = $this->security_settings; 1510 $smarty_compiler->trusted_dir = $this->trusted_dir; 1511 $smarty_compiler->_reg_objects = &$this->_reg_objects; 1512 $smarty_compiler->_plugins = &$this->_plugins; 1513 $smarty_compiler->_tpl_vars = &$this->_tpl_vars; 1514 $smarty_compiler->default_modifiers = $this->default_modifiers; 1515 $smarty_compiler->compile_id = $this->_compile_id; 1516 $smarty_compiler->_config = $this->_config; 1517 $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals; 1518 1519 $smarty_compiler->_cache_serial = null; 1520 $smarty_compiler->_cache_include = $cache_include_path; 1521 1522 1523 $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content); 1524 1525 if ($smarty_compiler->_cache_serial) { 1526 $this->_cache_include_info = array( 1527 'cache_serial'=>$smarty_compiler->_cache_serial 1528 ,'plugins_code'=>$smarty_compiler->_plugins_code 1529 ,'include_file_path' => $cache_include_path); 1530 1531 } else { 1532 $this->_cache_include_info = null; 1533 1534 } 1535 1536 return $_results; 1537 } 1538 1539 /** 1540 * Get the compile path for this resource 1541 * 1542 * @param string $resource_name 1543 * @return string results of {@link _get_auto_filename()} 1544 */ 1545 function _get_compile_path($resource_name) 1546 { 1547 return $this->_get_auto_filename($this->compile_dir, $resource_name, 1548 $this->_compile_id) . '.php'; 1549 } 1550 1551 /** 1552 * fetch the template info. Gets timestamp, and source 1553 * if get_source is true 1554 * 1555 * sets $source_content to the source of the template, and 1556 * $resource_timestamp to its time stamp 1557 * @param string $resource_name 1558 * @param string $source_content 1559 * @param integer $resource_timestamp 1560 * @param boolean $get_source 1561 * @param boolean $quiet 1562 * @return boolean 1563 */ 1564 1565 function _fetch_resource_info(&$params) 1566 { 1567 if(!isset($params['get_source'])) { $params['get_source'] = true; } 1568 if(!isset($params['quiet'])) { $params['quiet'] = false; } 1569 1570 $_return = false; 1571 $_params = array('resource_name' => $params['resource_name']) ; 1572 if (isset($params['resource_base_path'])) 1573 $_params['resource_base_path'] = $params['resource_base_path']; 1574 1575 if ($this->_parse_resource_name($_params)) { 1576 $_resource_type = $_params['resource_type']; 1577 $_resource_name = $_params['resource_name']; 1578 switch ($_resource_type) { 1579 case 'file': 1580 if ($params['get_source']) { 1581 $params['source_content'] = $this->_read_file($_resource_name); 1582 } 1583 $params['resource_timestamp'] = filemtime($_resource_name); 1584 $_return = is_file($_resource_name); 1585 break; 1586 1587 default: 1588 // call resource functions to fetch the template source and timestamp 1589 if ($params['get_source']) { 1590 $_source_return = isset($this->_plugins['resource'][$_resource_type]) && 1591 call_user_func_array($this->_plugins['resource'][$_resource_type][0][0], 1592 array($_resource_name, &$params['source_content'], &$this)); 1593 } else { 1594 $_source_return = true; 1595 } 1596 1597 $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) && 1598 call_user_func_array($this->_plugins['resource'][$_resource_type][0][1], 1599 array($_resource_name, &$params['resource_timestamp'], &$this)); 1600 1601 $_return = $_source_return && $_timestamp_return; 1602 break; 1603 } 1604 } 1605 1606 if (!$_return) { 1607 // see if we can get a template with the default template handler 1608 if (!empty($this->default_template_handler_func)) { 1609 if (!is_callable($this->default_template_handler_func)) { 1610 $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist."); 1611 } else { 1612 $_return = call_user_func_array( 1613 $this->default_template_handler_func, 1614 array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this)); 1615 } 1616 } 1617 } 1618 1619 if (!$_return) { 1620 if (!$params['quiet']) { 1621 $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"'); 1622 } 1623 } else if ($_return && $this->security) { 1624 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.is_secure.php'); 1625 if (!smarty_core_is_secure($_params, $this)) { 1626 if (!$params['quiet']) 1627 $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed'); 1628 $params['source_content'] = null; 1629 $params['resource_timestamp'] = null; 1630 return false; 1631 } 1632 } 1633 return $_return; 1634 } 1635 1636 1637 /** 1638 * parse out the type and name from the resource 1639 * 1640 * @param string $resource_base_path 1641 * @param string $resource_name 1642 * @param string $resource_type 1643 * @param string $resource_name 1644 * @return boolean 1645 */ 1646 1647 function _parse_resource_name(&$params) 1648 { 1649 1650 // split tpl_path by the first colon 1651 $_resource_name_parts = explode(':', $params['resource_name'], 2); 1652 1653 if (count($_resource_name_parts) == 1) { 1654 // no resource type given 1655 $params['resource_type'] = $this->default_resource_type; 1656 $params['resource_name'] = $_resource_name_parts[0]; 1657 } else { 1658 if(strlen($_resource_name_parts[0]) == 1) { 1659 // 1 char is not resource type, but part of filepath 1660 $params['resource_type'] = $this->default_resource_type; 1661 $params['resource_name'] = $params['resource_name']; 1662 } else { 1663 $params['resource_type'] = $_resource_name_parts[0]; 1664 $params['resource_name'] = $_resource_name_parts[1]; 1665 } 1666 } 1667 1668 if ($params['resource_type'] == 'file') { 1669 if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $params['resource_name'])) { 1670 // relative pathname to $params['resource_base_path'] 1671 // use the first directory where the file is found 1672 if (isset($params['resource_base_path'])) { 1673 $_resource_base_path = (array)$params['resource_base_path']; 1674 } else { 1675 $_resource_base_path = (array)$this->template_dir; 1676 $_resource_base_path[] = '.'; 1677 } 1678 foreach ($_resource_base_path as $_curr_path) { 1679 $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name']; 1680 if (file_exists($_fullpath) && is_file($_fullpath)) { 1681 $params['resource_name'] = $_fullpath; 1682 return true; 1683 } 1684 // didn't find the file, try include_path 1685 $_params = array('file_path' => $_fullpath); 1686 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php'); 1687 if(smarty_core_get_include_path($_params, $this)) { 1688 $params['resource_name'] = $_params['new_file_path']; 1689 return true; 1690 } 1691 } 1692 return false; 1693 } 1694 } elseif (empty($this->_plugins['resource'][$params['resource_type']])) { 1695 $_params = array('type' => $params['resource_type']); 1696 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_resource_plugin.php'); 1697 smarty_core_load_resource_plugin($_params, $this); 1698 } 1699 1700 return true; 1701 } 1702 1703 1704 /** 1705 * Handle modifiers 1706 * 1707 * @param string|null $modifier_name 1708 * @param array|null $map_array 1709 * @return string result of modifiers 1710 */ 1711 function _run_mod_handler() 1712 { 1713 $_args = func_get_args(); 1714 list($_modifier_name, $_map_array) = array_splice($_args, 0, 2); 1715 list($_func_name, $_tpl_file, $_tpl_line) = 1716 $this->_plugins['modifier'][$_modifier_name]; 1717 1718 $_var = $_args[0]; 1719 foreach ($_var as $_key => $_val) { 1720 $_args[0] = $_val; 1721 $_var[$_key] = call_user_func_array($_func_name, $_args); 1722 } 1723 return $_var; 1724 } 1725 1726 /** 1727 * Remove starting and ending quotes from the string 1728 * 1729 * @param string $string 1730 * @return string 1731 */ 1732 function _dequote($string) 1733 { 1734 if (($string{0} == "'" || $string{0} == '"') && 1735 $string{strlen($string)-1} == $string{0}) 1736 return substr($string, 1, -1); 1737 else 1738 return $string; 1739 } 1740 1741 1742 /** 1743 * read in a file from line $start for $lines. 1744 * read the entire file if $start and $lines are null. 1745 * 1746 * @param string $filename 1747 * @param integer $start 1748 * @param integer $lines 1749 * @return string 1750 */ 1751 function _read_file($filename, $start=null, $lines=null) 1752 { 1753 if (!($fd = @fopen($filename, 'r'))) { 1754 return false; 1755 } 1756 flock($fd, LOCK_SH); 1757 if ($start == null && $lines == null) { 1758 // read the entire file 1759 $contents = fread($fd, filesize($filename)); 1760 } else { 1761 if ( $start > 1 ) { 1762 // skip the first lines before $start 1763 for ($loop=1; $loop < $start; $loop++) { 1764 fgets($fd, 65536); 1765 } 1766 } 1767 if ( $lines == null ) { 1768 // read the rest of the file 1769 while (!feof($fd)) { 1770 $contents .= fgets($fd, 65536); 1771 } 1772 } else { 1773 // read up to $lines lines 1774 for ($loop=0; $loop < $lines; $loop++) { 1775 $contents .= fgets($fd, 65536); 1776 if (feof($fd)) { 1777 break; 1778 } 1779 } 1780 } 1781 } 1782 fclose($fd); 1783 return $contents; 1784 } 1785 1786 /** 1787 * get a concrete filename for automagically created content 1788 * 1789 * @param string $auto_base 1790 * @param string $auto_source 1791 * @param string $auto_id 1792 * @return string 1793 * @staticvar string|null 1794 * @staticvar string|null 1795 */ 1796 function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null) 1797 { 1798 $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; 1799 1800 if(@is_dir($auto_base)) { 1801 $_return = $auto_base . DIRECTORY_SEPARATOR; 1802 } else { 1803 // auto_base not found, try include_path 1804 $_params = array('file_path' => $auto_base); 1805 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php'); 1806 smarty_core_get_include_path($_params, $this); 1807 $_return = isset($_params['new_file_path']) ? $_params['new_file_path'] . DIRECTORY_SEPARATOR : null; 1808 } 1809 1810 if(isset($auto_id)) { 1811 // make auto_id safe for directory names 1812 $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id))); 1813 // split into separate directories 1814 $_return .= $auto_id . $_compile_dir_sep; 1815 } 1816 1817 if(isset($auto_source)) { 1818 // make source name safe for filename 1819 $_filename = urlencode(basename($auto_source)); 1820 $_crc32 = crc32($auto_source) . $_compile_dir_sep; 1821 // prepend %% to avoid name conflicts with 1822 // with $params['auto_id'] names 1823 $_crc32 = '%%' . substr($_crc32,0,3) . $_compile_dir_sep . '%%' . $_crc32; 1824 $_return .= $_crc32 . $_filename; 1825 } 1826 1827 return $_return; 1828 } 1829 1830 /** 1831 * unlink a file, possibly using expiration time 1832 * 1833 * @param string $resource 1834 * @param integer $exp_time 1835 */ 1836 function _unlink($resource, $exp_time = null) 1837 { 1838 if(isset($exp_time)) { 1839 if(time() - @filemtime($resource) >= $exp_time) { 1840 return @unlink($resource); 1841 } 1842 } else { 1843 return @unlink($resource); 1844 } 1845 } 1846 1847 /** 1848 * returns an auto_id for auto-file-functions 1849 * 1850 * @param string $cache_id 1851 * @param string $compile_id 1852 * @return string|null 1853 */ 1854 function _get_auto_id($cache_id=null, $compile_id=null) { 1855 if (isset($cache_id)) 1856 return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id; 1857 elseif(isset($compile_id)) 1858 return $compile_id; 1859 else 1860 return null; 1861 } 1862 1863 /** 1864 * trigger Smarty plugin error 1865 * 1866 * @param string $error_msg 1867 * @param string $tpl_file 1868 * @param integer $tpl_line 1869 * @param string $file 1870 * @param integer $line 1871 * @param integer $error_type 1872 */ 1873 function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null, 1874 $file = null, $line = null, $error_type = E_USER_ERROR) 1875 { 1876 if(isset($file) && isset($line)) { 1877 $info = ' ('.basename($file).", line $line)"; 1878 } else { 1879 $info = null; 1880 } 1881 if (isset($tpl_line) && isset($tpl_file)) { 1882 trigger_error("Smarty error: [in " . $tpl_file . " line " . 1883 $tpl_line . "]: $error_msg$info", $error_type); 1884 } else { 1885 trigger_error("Smarty error: $error_msg$info", $error_type); 1886 } 1887 } 1888 1889 1890 /** 1891 * callback function for preg_replace, to call a non-cacheable block 1892 * @return string 1893 */ 1894 function _process_compiled_include_callback($match) { 1895 $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3]; 1896 ob_start(); 1897 $_func($this); 1898 $_ret = ob_get_contents(); 1899 ob_end_clean(); 1900 return $_ret; 1901 } 1902 1903 1904 /** 1905 * called for included templates 1906 * 1907 * @param string $_smarty_include_tpl_file 1908 * @param string $_smarty_include_vars 1909 */ 1910 1911 // $_smarty_include_tpl_file, $_smarty_include_vars 1912 1913 function _smarty_include($params) 1914 { 1915 if ($this->debugging) { 1916 $_params = array(); 1917 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); 1918 $debug_start_time = smarty_core_get_microtime($_params, $this); 1919 $this->_smarty_debug_info[] = array('type' => 'template', 1920 'filename' => $params['smarty_include_tpl_file'], 1921 'depth' => ++$this->_inclusion_depth); 1922 $included_tpls_idx = count($this->_smarty_debug_info) - 1; 1923 } 1924 1925 $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']); 1926 1927 // config vars are treated as local, so push a copy of the 1928 // current ones onto the front of the stack 1929 array_unshift($this->_config, $this->_config[0]); 1930 1931 $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']); 1932 1933 1934 if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path) 1935 || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path)) 1936 { 1937 include($_smarty_compile_path); 1938 } 1939 1940 // pop the local vars off the front of the stack 1941 array_shift($this->_config); 1942 1943 $this->_inclusion_depth--; 1944 1945 if ($this->debugging) { 1946 // capture time for debugging info 1947 $_params = array(); 1948 require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); 1949 $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time; 1950 } 1951 1952 if ($this->caching) { 1953 $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true; 1954 } 1955 } 1956 1957 1958 /** 1959 * get or set an array of cached attributes for function that is 1960 * not cacheable 1961 * @return array 1962 */ 1963 function &_smarty_cache_attrs($cache_serial, $count) { 1964 $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count]; 1965 1966 if ($this->_cache_including) { 1967 /* return next set of cache_attrs */ 1968 $_return =& current($_cache_attrs); 1969 next($_cache_attrs); 1970 return $_return; 1971 1972 } else { 1973 /* add a reference to a new set of cache_attrs */ 1974 $_cache_attrs[] = array(); 1975 return $_cache_attrs[count($_cache_attrs)-1]; 1976 1977 } 1978 1979 } 1980 1981 1982 /** 1983 * wrapper for include() retaining $this 1984 * @return mixed 1985 */ 1986 function _include($filename, $once=false, $params=null) 1987 { 1988 if ($once) { 1989 return include_once($filename); 1990 } else { 1991 return include($filename); 1992 } 1993 } 1994 1995 1996 /** 1997 * wrapper for eval() retaining $this 1998 * @return mixed 1999 */ 2000 function _eval($code, $params=null) 2001 { 2002 return eval($code); 2003 } 2004 /**#@-*/ 2005 2006} 2007 2008/* vim: set expandtab: */ 2009 2010?> 2011