Compare commits

..

491 Commits

Author SHA1 Message Date
uwetews d234f79203 Prepare release 3.1.28 2015-12-13 15:19:58 +01:00
uwetews 15e3d10267 Fix typos 2015-12-13 15:16:20 +01:00
uwetews 2cab5c74ff fix link to documentation 2015-12-13 14:50:11 +01:00
uwetews dca9cd887e Merge pull request #117 from yonexyonex/fix_typo
fix typo in template error message
2015-12-13 14:41:20 +01:00
yonex fc999d81be fix typo in template error message 2015-12-13 22:35:22 +09:00
uwetews e8078f55ae - bugfix Debug Console could display incorrect data when using subtemplates 2015-12-13 14:15:54 +01:00
uwetews 7e521a92d9 - bugfix $smarty->debugging_ctrl = 'URL' did not work (forum topic 25811) 2015-12-13 10:16:10 +01:00
uwetews 6dc9196c35 - bugfix {foreach} and {section} with uppercase characters in name attribute did not work (forum topic 25819) 2015-12-13 06:30:08 +01:00
uwetews 71e364e4b2 - bugix Smarty did fail under PHP 7.0.0 with use_include_path = true; 2015-12-09 02:16:48 +01:00
uwetews e783f61132 - bugix Smarty did fail under PHP 7.0.0 with use_include_path = true; 2015-12-09 02:03:56 +01:00
uwetews 260d3e3e46 -bugfix {strip} should exclude some html tags from stripping, related to fix for https://github.com/smarty-php/smarty/issues/111 2015-12-09 01:35:17 +01:00
uwetews ee743d2729 update of SMARTY_VERSION 2015-12-08 23:45:04 +01:00
uwetews 29e2eb0bca - bugfix internal template function data got stored in wrong compiled file https://github.com/smarty-php/smarty/issues/114 2015-12-08 23:41:42 +01:00
uwetews be8340bef2 - remove no longer needed file and updated testinstall 2015-12-08 23:41:01 +01:00
uwetews 4839d0e0cc -bugfix {strip} should insert a single space https://github.com/smarty-php/smarty/issues/111 2015-12-05 17:28:05 +01:00
uwetews 54fe432730 Merge pull request #109 from KLVTZ/master
Refactor readme: use github markdown parser
2015-12-04 04:11:16 +01:00
Justin Page a061365844 Provide new line to separate highlights 2015-11-28 16:51:14 -08:00
Justin Page 0403c876ed Use quotes to highlight features 2015-11-28 16:48:27 -08:00
Justin Page 2bc86a00f1 Wrap JSON examples in language specific code wrap
This allows Github or any repo system to parse and display correctly code
examples by proper wrappers.
2015-11-28 16:45:46 -08:00
uwetews e0fc310b6e -bugfix a left delimter like '[%' did fail on [%$var_[%$variable%]%] (forum topic 25798) 2015-11-25 21:19:23 +01:00
uwetews 5ca1cd485f - bugfix {include} with variable file name like {include file="foo_$bar.tpl"} did fail in 3.1.28-dev https://github.com/smarty-php/smarty/issues/102 2015-11-02 23:04:52 +01:00
uwetews aa730800bd - bugfix {include} with variable file name like {include file="foo_$bar.tpl"} did fail in 3.1.28-dev https://github.com/smarty-php/smarty/issues/102 2015-11-02 18:06:42 +01:00
uwetews cc3f69a2a3 - update config file processing 2015-11-01 02:58:27 +01:00
uwetews 8a78038181 update PHPdoc 2015-11-01 02:57:50 +01:00
uwetews 72258bc28d add test for valid scope name 2015-11-01 02:02:27 +01:00
uwetews 9496df8e1f - bugfix add missing $trusted_dir property to SmartyBC class (forum topic 25751) 2015-10-31 23:13:12 +01:00
uwetews eedfdff62f - improve template scope handling 2015-10-29 22:33:00 +01:00
uwetews 55f38125a4 - improve template scope handling 2015-10-29 22:17:35 +01:00
uwetews a0f583078d - minor optimizations 2015-10-29 21:41:21 +01:00
uwetews 862b23fe52 - update testinstall() 2015-10-26 01:27:06 +01:00
uwetews 6e3d94c13e - more optimizations of template processing 2015-10-25 05:59:45 +01:00
uwetews 2b9dcb22b5 - more optimizations of template processing 2015-10-25 05:03:23 +01:00
uwetews 42e722926a - bugfix Error when using {include} within {capture} https://github.com/smarty-php/smarty/issues/100 2015-10-25 04:53:58 +01:00
uwetews 1a51c1c17b - more optimizations of template processing 2015-10-25 04:53:19 +01:00
uwetews 50760c794c - more optimizations of template processing 2015-10-24 22:43:19 +02:00
uwetews 4ea4d1ff41 - improve autoloader speed 2015-10-24 05:20:09 +02:00
uwetews abdb335b26 - fix comment 2015-10-24 05:17:17 +02:00
uwetews b7fb490cb1 - improve compiled code 2015-10-24 05:16:54 +02:00
uwetews 891495f849 - improve recovery from ivalid compiled template code 2015-10-24 05:14:47 +02:00
uwetews 0ea1360d65 - new extension handler to load functions when called 2015-10-24 05:12:10 +02:00
uwetews 888014b908 - new extension handler to load functions when called 2015-10-24 05:02:24 +02:00
uwetews eec7639c9c - fix template scope processing 2015-10-24 04:45:09 +02:00
uwetews b26ba9ce52 update travis 2015-10-21 04:32:27 +02:00
uwetews e25a8ab661 - move some code into runtime extensions 2015-10-21 03:53:25 +02:00
uwetews ad65c850f7 - move some code into runtime extensions 2015-10-21 02:02:42 +02:00
uwetews 4e1d6707fe - update code generated by template function call handler 2015-10-18 22:12:16 +02:00
uwetews 0e28150b4a - fix compiled code for new {block} assign attribute 2015-10-18 11:35:08 +02:00
uwetews bd7d10e09d Update travis 2015-10-18 05:14:27 +02:00
uwetews bf6910ee21 - bugfix under HHVM temporary cache file must only be created when caches template was updated 2015-10-18 05:08:03 +02:00
uwetews 4776491a7f - bugfix under HHVM temporary cache file must only be created when caches template was updated 2015-10-18 04:58:53 +02:00
uwetews c99fe144f6 - speed and size optimizations 2015-10-18 04:54:09 +02:00
uwetews 8dc2a0af7c - rework of template inheritance 2015-10-18 04:46:05 +02:00
uwetews ca9ccfc919 - optimize filepath normalization 2015-10-18 04:40:45 +02:00
uwetews 757d66a731 parser: add support for template prefix and postfix code 2015-10-18 02:02:43 +02:00
uwetews 5cde3a8799 compiler: add support for post compile callbacks 2015-10-18 02:02:42 +02:00
uwetews 8dc777effd Merge pull request #96 from glensc/patch-1
do not load "Autoloader" from include path
2015-10-18 02:00:49 +02:00
Elan Ruusamäe 87a04b2ef6 do not load "Autoloader" from include path
loading it from include path (without abs path) can be dangerous, can load some other project's Autoloader.php instead the right one.
2015-10-13 10:32:04 +03:00
uwetews 788566cf70 - bugfix {if $foo instanceof $bar} failed to compile if 2nd value is a variable https://github.com/smarty-php/smarty/issues/92 (reverted from commit 428e667453) 2015-10-08 19:53:25 +02:00
uwetews 428e667453 - bugfix {if $foo instanceof $bar} failed to compile if 2nd value is a variable https://github.com/smarty-php/smarty/issues/92 2015-10-08 19:47:43 +02:00
uwetews 7f0a2f788f Merge pull request #95 from dshepherd/patch-1
Update README with correct plugin method signature
2015-10-08 19:42:03 +02:00
Dan Shepherd d45652afe2 Update README with correct plugin method signature
The existing README states that 3 params are passed for plugins (params, smarty, template) but the smarty object was actually removed long ago. This update correct this.
2015-10-08 13:50:46 +01:00
uwetews 64464e8fbe - bugfix {if $foo instanceof $bar} failed to compile if 2nd value is a variable https://github.com/smarty-php/smarty/issues/92 2015-09-19 19:55:14 +02:00
uwetews d5ca4518be - bugfix {foreach} first attribute was not correctly reset since commit 05a8fa2 of 02.08.2015 https://github.com/smarty-php/smarty/issues/90 2015-09-17 21:01:48 +02:00
uwetews e1e8d2feda - update compiler by moving no longer needed properties, code optimizations and other 2015-09-16 16:23:38 +02:00
uwetews 5a9500c2d9 - remove not needed compiled code whan caching is disabled 2015-09-15 01:25:40 +02:00
uwetews 83a68c99c8 - update template inheritance processing 2015-09-15 00:44:34 +02:00
uwetews fb9f2c9267 fix 2015-09-15 00:21:28 +02:00
uwetews ceb9afbb5d - bugfix unintended multiple debug windows (forum topic 25699) 2015-09-15 00:18:17 +02:00
uwetews 0eb7f4b8d1 - improvement invalidate OPCACHE for cleared compiled and cached template files (forum topic 25557) 2015-09-15 00:15:12 +02:00
uwetews 6ff3505a37 - move code of {call} processing back into Smarty_Internal_Template class 2015-09-14 23:50:20 +02:00
uwetews 8d734a9d52 - update template inheritance processing 2015-09-14 23:46:17 +02:00
uwetews 71c1b32c51 - optimize internal subtemplate handling 2015-09-14 23:39:04 +02:00
uwetews 5cbedc87f0 - optimize internal subtemplate handling 2015-09-14 23:16:13 +02:00
uwetews df0824675a - optimize internal subtemplate handling 2015-09-14 23:12:03 +02:00
uwetews 56a884a428 - optimize autoloader 2015-09-14 23:02:59 +02:00
uwetews bfcffb009a - remove unneeded code and properties, minor fixes 2015-09-01 02:52:09 +02:00
uwetews ca0b3f02b9 add some cope needed for PHPunit tests 2015-09-01 02:35:51 +02:00
uwetews 2e0b834b59 remove unneeded realpath call 2015-09-01 02:34:59 +02:00
uwetews d2fa4083f7 - move template function code into runtime extension 2015-09-01 02:30:56 +02:00
uwetews 2ba7109043 - move subtemplate code into runtime extension and optimize for size and speed 2015-09-01 02:27:22 +02:00
uwetews 37e6529c7b - improvement convert template inheritance into runtime processing
- bugfix {$smarty.block.parent} did always reference the root parent block https://github.com/smarty-php/smarty/issues/68
2015-09-01 02:10:15 +02:00
uwetews 620e52405b - improvement convert template inheritance into runtime processing
- bugfix {$smarty.block.parent} did always reference the root parent block https://github.com/smarty-php/smarty/issues/68
2015-09-01 01:54:28 +02:00
uwetews 54d54e5000 hook for runtime extension loading 2015-09-01 00:33:10 +02:00
uwetews 0d46c17578 - rearrange internal cache 2015-08-29 14:37:59 +02:00
uwetews 31a7162fba - remove double break 2015-08-27 19:26:49 +02:00
uwetews 3ba86e8d91 remove permission properties 2015-08-23 19:58:27 +02:00
uwetews d67acf7e9a revert removal of permission properties 2015-08-23 18:46:32 +02:00
uwetews 470cd186c4 major push of internal changes for size and speed optimizations 2015-08-23 17:23:09 +02:00
uwetews 0e4039f5c0 - bugfix compiling super globals like {$smarty.get.foo} did fail in the master branch https://github.com/smarty-php/smarty/issues/77 2015-08-23 16:59:34 +02:00
uwetews 9fd0b3086d - remove redundant code 2015-08-23 13:53:03 +02:00
uwetews 9eb87ef5a2 - relocate properties for size optimization 2015-08-23 13:24:24 +02:00
uwetews 606b8e8669 - optimize use_include_path processing 2015-08-23 11:13:20 +02:00
uwetews 2c197a2ea6 - check if $includes entry does exist 2015-08-23 06:47:39 +02:00
uwetews 3382aab429 - fix output buffer handling 2015-08-23 06:46:03 +02:00
uwetews 0b9e46d6ed - bugfix do not cache template object for config files 2015-08-23 05:36:20 +02:00
uwetews c6ea69feb7 - bugfix uncompiled templates could not be cached after recent change 2015-08-23 05:35:13 +02:00
uwetews 3daf187fb1 - bugfix of unneeded instanceof conditions replacement 2015-08-23 05:33:04 +02:00
uwetews 189b2af115 - optimize invalidation of internal caches 2015-08-23 05:27:16 +02:00
uwetews 1ae11c26c0 - optimize Smarty::templateExists() 2015-08-23 05:15:05 +02:00
uwetews fb83a888f3 varname changes 2015-08-23 02:03:25 +02:00
uwetews e2f11126eb fix PHPDoc 2015-08-23 02:00:25 +02:00
uwetews a413a2a2e1 replace unneeded instanceof conditions 2015-08-23 01:50:05 +02:00
uwetews 6eed7732df - remove properties with redundant content 2015-08-23 01:46:30 +02:00
uwetews 87985d1243 - move caching to Smarty::_cache 2015-08-23 01:39:18 +02:00
uwetews 6a26393099 - optimize rendering 2015-08-23 01:26:46 +02:00
uwetews 329cd6ec4d - remove not really needed properties 2015-08-19 02:19:25 +02:00
uwetews df541858de - cache template object of {include} if same template is included several times 2015-08-19 01:22:27 +02:00
uwetews 7935b181fb - optimize nocache hash processing 2015-08-19 01:18:25 +02:00
uwetews 8292a3581c - use output buffers for better performance and less memory usage 2015-08-19 01:09:08 +02:00
uwetews 6087ac5de0 - convert debug console processing to object 2015-08-19 00:58:47 +02:00
uwetews 5f7b5a45ac improve performance 2015-08-18 03:20:01 +02:00
uwetews 457a0486f5 - cache template object of {include} if same template is included several times 2015-08-18 02:55:53 +02:00
uwetews e8252906ba - make sure that property value is set 2015-08-17 22:27:41 +02:00
uwetews 6cbcdf4d7b - load seldom used Smarty API methods dynamically to reduce memory footprint 2015-08-17 21:52:32 +02:00
uwetews eb7aa8fe92 update template_id handling 2015-08-15 18:35:51 +02:00
uwetews 8a9b52e975 optimize $properties array 2015-08-15 18:32:27 +02:00
uwetews 9ad5e1eb1e define missing properties 2015-08-15 18:25:06 +02:00
uwetews af6f77a9e6 create raw compiled object to avoid checking for compiled file 2015-08-10 22:45:56 +02:00
uwetews e63926088c optimize compilation of merged subtemplates 2015-08-10 22:35:33 +02:00
uwetews 0260b525b8 introduce Smarty::$resource_cache_mode and cache template object of {include} inside loop 2015-08-10 21:57:06 +02:00
uwetews 5c9c57df7d replace property array by object properties 2015-08-09 21:14:16 +02:00
uwetews 6bcdd0edbe remove unused parameter 2015-08-09 20:56:18 +02:00
uwetews dde6bc506b remove unneeded method 2015-08-09 20:54:13 +02:00
uwetews 7d2e27ae2f use parent_compiler object for storing required plugins 2015-08-09 20:53:32 +02:00
uwetews 3619b672f4 replace property array by object properties 2015-08-09 20:48:33 +02:00
uwetews c08191d191 replace property array by object properties 2015-08-09 20:45:28 +02:00
uwetews d16e2d3a15 replace property array by object properties 2015-08-09 20:43:04 +02:00
Uwe Tews 643e6784e8 - bugfix Smarty failed when compile_id did contain "|" 2015-08-06 21:42:20 +02:00
Uwe Tews c5cf7884d5 - commit several internal improvements 2015-08-06 19:46:44 +02:00
Uwe Tews ea6f848e04 fix properties 2015-08-06 19:42:40 +02:00
Uwe Tews 5d1ba7ca9c restore template object state on exception, free lexer/parser resources 2015-08-06 19:40:37 +02:00
Uwe Tews e402e2f893 no need to clone handler 2015-08-06 19:32:33 +02:00
Uwe Tews de49865d22 optimize template object caching 2015-08-06 19:25:00 +02:00
Uwe Tews 16fc95ccf7 load source resource at template object creation 2015-08-06 19:16:41 +02:00
Uwe Tews 1ed4808bd9 check parent object type 2015-08-06 19:14:55 +02:00
Uwe Tews 5ca4f0484a load source resource at template object creation 2015-08-06 19:12:24 +02:00
Uwe Tews 35c7e9767d remove unneeded properties 2015-08-06 19:05:11 +02:00
Uwe Tews 8cffee8426 invalidate compiled resource cache 2015-08-06 19:02:30 +02:00
Uwe Tews 63a1e74811 - rewrite compileAll... utility methods 2015-08-06 01:29:36 +02:00
Uwe Tews a7098432ba Make declaration compatible with compile assign 2015-08-06 01:24:41 +02:00
Uwe Tews e1cc514a68 - avoid possible circular object referances caused by parser/lexer objects 2015-08-06 01:19:11 +02:00
Uwe Tews ca969fe663 fix autoloader optimization 2015-08-06 00:59:06 +02:00
Uwe Tews 8c5f20430d optimize duplicate code 2015-08-06 00:57:36 +02:00
Uwe Tews 80ee385965 - improve getIncludePath() to return directory i 2015-08-03 22:32:09 +02:00
Uwe Tews 201ea13a33 - bugfix compileAllConfig() was broken since 3.1.22 because of the changes in config file processing 2015-08-03 21:39:30 +02:00
Uwe Tews f2585a035c - rework clear cache methods 2015-08-03 05:40:34 +02:00
Uwe Tews 147ba329b5 Fix generated code 2015-08-03 03:14:25 +02:00
Uwe Tews 7dfe853076 remove unneed dummy $smarty template variable 2015-08-02 21:12:33 +02:00
Uwe Tews c95ff14434 - rework {capture} compiler 2015-08-02 20:57:46 +02:00
Uwe Tews e205cb7a89 - optimization and code cleanup of {foreach} and {section} compiler 2015-08-02 19:43:21 +02:00
Uwe Tews 05a8fa245e - improvement show resource type and start of template source instead of uid on eval: and string: resource (forum topic 25630) 2015-08-01 14:28:39 +02:00
Uwe Tews 3d2a15be3c - update DateTime object can be instance of DateTimeImmutable since PHP5.5 https://github.com/smarty-php/smarty/pull/75 2015-08-01 13:09:41 +02:00
Uwe Tews c5cdd90352 - optimize {foreach} and {section} compiler 2015-07-31 01:03:29 +02:00
Uwe Tews e9d172d8ac - optimize {section} compiler for speed and size of compiled code 2015-07-30 02:45:38 +02:00
Uwe Tews 20640577a1 Revert "- optimize {section} compiler for speed and size of compiled code"
This reverts commit 1074090473.
2015-07-30 02:03:29 +02:00
Uwe Tews 1074090473 - optimize {section} compiler for speed and size of compiled code 2015-07-30 01:15:22 +02:00
Uwe Tews aa6e2219ec - optimize {section} compiler for speed and size of compiled code 2015-07-30 01:03:12 +02:00
Uwe Tews 8eabafed83 add some error suppression for undefined variables 2015-07-29 23:30:52 +02:00
Uwe Tews 99d802f30c - optimize {section} compiler for speed and size of compiled code 2015-07-29 22:23:23 +02:00
Uwe Tews c9f2a0d26e - update for PHP 7 compatibility 2015-07-28 01:39:08 +02:00
Uwe Tews fe4fdd15d8 add PHP 7 to travis tests 2015-07-28 01:15:31 +02:00
Uwe Tews d192e470d5 add PHP 7 to travis tests 2015-07-28 01:12:45 +02:00
Uwe Tews 0436176739 add hhvm to travis test 2015-07-26 18:11:10 +02:00
Uwe Tews f9d9ca0f67 - improvement impement workaround for HHVM PHP incompatibillity https://github.com/facebook/hhvm/issues/4797 2015-07-26 18:04:40 +02:00
Uwe Tews bb3dfc6fdf - bugfix parser did hang on text starting <?something https://github.com/smarty-php/smarty/issues/74 2015-07-25 22:32:10 +02:00
Uwe Tews f61084f70f move Smarty::clear() into extension 2015-07-20 04:38:13 +02:00
Uwe Tews 8cbe51a603 - improvement invalidate PHP 5.5 opcache for recompiled and cached templates https://github.com/smarty-php/smarty/issues/72 2015-07-20 04:01:43 +02:00
Uwe Tews 3e54c268ab - bugfix config files got recompiled on each request 2015-07-20 03:15:45 +02:00
Uwe Tews 61253c1999 optimization 2015-07-12 07:03:55 +02:00
Uwe Tews 208628080f reformat 2015-07-12 07:02:25 +02:00
Uwe Tews 21e07daf6d optimization 2015-07-12 02:26:42 +02:00
Uwe Tews 878724c4ea - optimize {extends} compilation 2015-07-12 01:11:22 +02:00
Uwe Tews b3fd262541 - bugfix force file: resource in demo resource.extendsall.php 2015-07-10 05:18:10 +02:00
Uwe Tews 7a56edc180 - bugfix convert each word of class names to ucfirst in in compiler. (forum topic 25588) 2015-07-08 04:59:37 +02:00
Uwe Tews 40f0dda0e6 - new feature multiple indices on file: resource 2015-07-07 18:18:19 +02:00
Uwe Tews 1e4f28da54 update Smarty::_realpath() 2015-07-07 17:56:50 +02:00
Uwe Tews 7fa6c4fd47 update include_path handling 2015-07-07 17:55:45 +02:00
Uwe Tews 733755f94a reformat 2015-07-07 17:51:40 +02:00
uwetews f66cd7e062 Merge pull request #71 from mmerian/master
Added $limit parameter to regex_replace modifier
2015-07-07 15:40:28 +02:00
Maxime Mérian 73dc3f311a Added $limit parameter to regex_replace modifier 2015-07-07 09:32:40 +02:00
Uwe Tews bc99747f93 - improvement allow fetch() or display() called on a template object to get output from other template
like $template->fetch('foo.tpl') https://github.com/smarty-php/smarty/issues/70
2015-07-07 02:01:45 +02:00
Uwe Tews 5b401789b5 - optimization resource extendsall 2015-07-06 06:57:56 +02:00
uwetews a35294946e Merge pull request #69 from bmewburn/master
removed invalid .gitignore pattern
2015-07-06 05:46:01 +02:00
Uwe Tews 06096191c5 - optimize {block} compilation 2015-07-06 03:41:37 +02:00
Uwe Tews b1fdc085e7 - optimization get rid of __get and __set in source object 2015-07-06 03:25:03 +02:00
Uwe Tews b198e6488c - optimize {block} compilation 2015-07-06 03:12:25 +02:00
bmewburn da38a22621 removed invalid .gitignore pattern
git ignore pattern .idea\ causes version control in netbeans 8.02 to crash
2015-07-06 11:12:11 +10:00
Uwe Tews 7e7112153a search {foreach} properties also in parent compiler 2015-07-01 13:01:16 +02:00
Uwe Tews e5bea506af - bugfix debugging console did not display string values containing \n, \r or \t correctly https://github.com/smarty-php/smarty/issues/66 2015-07-01 10:54:45 +02:00
Uwe Tews a756ce3d9e add error messages 2015-07-01 10:46:51 +02:00
Uwe Tews be212a2a87 load template source early 2015-07-01 06:44:28 +02:00
Uwe Tews 9ac1dd44e2 - update {foreach} compiler 2015-07-01 03:30:08 +02:00
Uwe Tews a9f0b8ad1f - optimize compile check handling 2015-07-01 03:27:06 +02:00
Uwe Tews 86783c857d use tag object cache of parent compiler 2015-07-01 03:25:55 +02:00
Uwe Tews 2762d81d93 add new methods and optimizations 2015-07-01 03:23:40 +02:00
Uwe Tews 8567f08248 fix flag in file status cache 2015-06-30 02:59:41 +02:00
Uwe Tews c84e406db5 observe $smarty->compile_check 2015-06-29 20:48:49 +02:00
Uwe Tews 83f6154eae - compiler optimization 2015-06-29 20:45:21 +02:00
Uwe Tews 3052406cfc - fix $smarty->use_include_path option and optimize file path code 2015-06-29 02:41:42 +02:00
Uwe Tews 99fe8120c8 - remove redundant code 2015-06-28 15:45:50 +02:00
Uwe Tews 8d30442450 - bugfix PATH_SEPARATOR was replaced by mistake in autoloader 2015-06-28 15:12:00 +02:00
Uwe Tews cd132140f2 - optimize file path normalization 2015-06-28 12:54:47 +02:00
Uwe Tews c1ae1a52af - optimize autoloader 2015-06-28 08:33:18 +02:00
Uwe Tews ce0c1dcfae - move $smarty->append() and $smarty->appendByRef() into extension 2015-06-28 05:22:19 +02:00
Uwe Tews 3442acd407 update comment 2015-06-28 05:00:47 +02:00
Uwe Tews f4d7838a8f - move getStreamVariable() into extension 2015-06-28 05:00:27 +02:00
Uwe Tews afe9af11b7 - move $smarty->getTemplateVars() into extension 2015-06-28 04:44:16 +02:00
Uwe Tews 85eb95d960 - move auto load filter methods into extension 2015-06-28 04:05:07 +02:00
Uwe Tews aee07f7bba - optimize security isTrustedResourceDir() 2015-06-28 02:37:41 +02:00
Uwe Tews 5377fd5926 - move $smarty->enableSecurity() into Smarty_Security class 2015-06-28 01:38:52 +02:00
Uwe Tews 15d8e545cd - rework of $smarty->clearCompiledTemplate() and move it to its own extension 2015-06-27 23:59:12 +02:00
Uwe Tews 9d937ffe68 - bugfix allow function plugins with name ending with 'close' https://github.com/smarty-php/smarty/issues/52 2015-06-27 22:18:08 +02:00
Uwe Tews 1360be4eef - minor compiler optimizations 2015-06-27 21:50:33 +02:00
Uwe Tews 38e47c7ee2 - minor compiler optimizations 2015-06-27 21:23:22 +02:00
Uwe Tews 291c06dbea - move $smarty->loadPlugin() into extension 2015-06-27 20:56:27 +02:00
Uwe Tews 75ccd86c8a - update {include_php} with new realpath handling 2015-06-27 20:25:54 +02:00
Uwe Tews f567d5d778 - update Smarty security with new realpath handling 2015-06-27 20:18:01 +02:00
Uwe Tews 6197df45b5 - update $smarty->_realpath for relative path not starting with './' 2015-06-27 20:08:17 +02:00
Uwe Tews aefec40962 - fix special cases of filepath normalization 2015-06-27 18:30:47 +02:00
Uwe Tews e0630b106a revert 2015-06-27 16:31:26 +02:00
Uwe Tews c5ea2e4b48 add hhvm 2015-06-27 16:26:31 +02:00
Uwe Tews 9986286af0 - bugfix resolve naming conflict between custom Smarty delimiter '<%' and PHP ASP tags https://github.com/smarty-php/smarty/issues/64 2015-06-27 16:09:50 +02:00
Uwe Tews 3239a19435 - bugfix resolve naming conflict between custom Smarty delimiter '<%' and PHP ASP tags https://github.com/smarty-php/smarty/issues/64 2015-06-27 15:35:27 +02:00
Uwe Tews 6b875397a5 update autoloader 2015-06-21 13:56:10 +02:00
Uwe Tews b64d5d26c9 - update realpath handling 2015-06-21 13:53:52 +02:00
Uwe Tews 666f7264f4 optimization 2015-06-21 13:51:50 +02:00
Uwe Tews dd4cbfac3a - move registerObject / registerClass into extension 2015-06-21 13:43:17 +02:00
Uwe Tews 1a24b3971d - optimization of filter execution 2015-06-21 13:23:23 +02:00
Uwe Tews c09b05cbe3 - optimization of directory handling / build realpath 2015-06-21 13:11:52 +02:00
Uwe Tews 31d94d05d3 - optimization of template/config file normalization 2015-06-21 12:52:49 +02:00
Uwe Tews 4e471b19e2 - optimization of template/config file normalization 2015-06-21 12:42:53 +02:00
Uwe Tews 2d0f457abd Update 2015-06-20 18:25:05 +02:00
Uwe Tews afe79aac2e - improvement allow closures as callback at $smarty->registerFilter() https://github.com/smarty-php/smarty/issues/59 2015-06-19 03:21:52 +02:00
Uwe Tews 4537d8aae6 Release 3.1.27 2015-06-18 02:55:59 +02:00
Uwe Tews 34531edb4c - bugfix another update on file path normalization failed on path containing something like "/.foo/" https://github.com/smarty-php/smarty/issues/56 2015-06-18 02:53:22 +02:00
Uwe Tews 2cdba79a74 Release 3.1.26 2015-06-18 02:08:42 +02:00
Uwe Tews 7b469c1f4a - bugfix file path normalization failed on path containing something like "/.foo/" https://github.com/smarty-php/smarty/issues/56 2015-06-18 01:46:35 +02:00
Uwe Tews 52ced72361 - bugfix calling a plugin with nocache option but no other attributes like {foo nocache} caused call to undefined function https://github.com/smarty-php/smarty/issues/55 2015-06-18 00:06:40 +02:00
Uwe Tews 58616d6ee5 Release 3.1.25 2015-06-16 00:23:24 +02:00
Uwe Tews ec383370cb - optimization of smarty_cachereource_keyvaluestore.php code 2015-06-15 23:39:42 +02:00
Uwe Tews 3bb22560c0 - bugfix an output tag with variable, modifier followed by an operator like {$foo|modifier+1} did fail https://github.com/smarty-php/smarty/issues/53 2015-06-14 04:26:37 +02:00
Uwe Tews 83f3f6d7f1 - bugfix an output tag with variable, modifier followed by an operator like {$foo|modifier+1} did fail https://github.com/smarty-php/smarty/issues/53 2015-06-14 04:23:50 +02:00
Uwe Tews ecddc1f720 - bugfix a relative sub template path could fail if template_dir path did contain /../ https://github.com/smarty-php/smarty/issues/50
- optimization rework of path normalization
2015-06-14 03:30:31 +02:00
Uwe Tews e96ee1b5d6 - bugfix a custom cache resource using smarty_cachereource_keyvaluestore.php did fail if php.ini mbstring.func_overload = 2 (forum topic 25568) 2015-06-13 19:39:02 +02:00
Uwe Tews 768b7d1ec5 - bugfix the lexer could hang on very large quoted strings (forum topic 25570) 2015-06-11 23:33:30 +02:00
Uwe Tews f1e1f56ffe - bugfix using {$foo} as array index like $bar.{$foo} or in double quoted string like "some {$foo} thing" failed https://github.com/smarty-php/smarty/issues/49 2015-06-08 23:54:46 +02:00
Uwe Tews d804454f21 Fix spelling 2015-06-04 02:40:36 +02:00
Uwe Tews 2a1badfebb - bugfix possible error message on unset() while compiling {block} tags https://github.com/smarty-php/smarty/issues/46 2015-06-04 02:39:26 +02:00
Uwe Tews fa269d418f - bugfix <?xml ... ?> including template variables broken since 3.1.22 https://github.com/smarty-php/smarty/issues/47 2015-06-01 22:26:45 +02:00
Uwe Tews 3771ea8d35 Fix comments 2015-05-28 22:31:35 +02:00
Uwe Tews 63b1d343b8 - bugfix {include} with variable file name must not create by default individual cache file (since 3.1.22) https://github.com/smarty-php/smarty/issues/43 2015-05-27 22:24:24 +02:00
Uwe Tews 0434f34bdd - bugfix if condition string 'neq' broken due to a typo https://github.com/smarty-php/smarty/issues/42 2015-05-24 18:37:53 +02:00
Uwe Tews c9cd39f36f minor bugfix when processing autoliteral { php} tag. Does not effect generated output. 2015-05-23 23:40:02 +02:00
Uwe Tews 0356b70578 minor fix 2015-05-23 22:40:24 +02:00
Uwe Tews aa1e554993 Remove redundant code 2015-05-23 22:36:46 +02:00
Uwe Tews 531b298886 Prepare 3.1.25-dev 2015-05-23 19:25:50 +02:00
Uwe Tews b58771e31b Release 3.1.24 2015-05-23 19:22:14 +02:00
Uwe Tews c226fbd3d9 Travis setup does not work for PHP 5.2 for some reason 2015-05-23 19:04:19 +02:00
Uwe Tews 25391749a1 - improvement on php_handling to allow very large PHP sections, better error handling
- improvement allow extreme large comment sections (forum 25538)
2015-05-23 19:03:13 +02:00
Uwe Tews ec449734c3 - improvement on php_handling to allow very large PHP sections, better error handling
- improvement allow extreme large comment sections (forum 25538)
2015-05-23 18:56:00 +02:00
Uwe Tews c8ecad0b06 - bugfix named {foreach} comparison like $smarty.foreach.foobar.index > 1 did compile into wrong code https://github.com/smarty-php/smarty/issues/41 2015-05-21 00:59:26 +02:00
Uwe Tews 5d8718f761 - bugfix broken PHP 5.2 compatibility when compiling <?php tags https://github.com/smarty-php/smarty/issues/40 2015-05-21 00:05:16 +02:00
Uwe Tews 85e05458c6 - bugfix compiler could run into the pcre.backtrack_limit on larger comment or {php} tag sections (forum 25538) 2015-05-20 05:48:45 +02:00
Uwe Tews b8eb8784d4 - bugfix output filter trimwhitespace could run into the pcre.backtrack_limit on large output (code.google issue 220) 2015-05-20 04:26:29 +02:00
Uwe Tews 5468f140fa - bugfix compiler did overwrite existing variable value when setting the nocache attribute https://github.com/smarty-php/smarty/issues/39 2015-05-19 22:47:04 +02:00
Uwe Tews dcf53ca957 Fix max nesting parameter 2015-05-18 05:39:57 +02:00
Uwe Tews ed740b967a Removed redundant code 2015-05-18 04:26:46 +02:00
Uwe Tews ac99173cea - improvement introduce shortcuts in lexer/parser rules for most frequent terms for higher
compilation speed
2015-05-18 04:12:40 +02:00
Uwe Tews bef7c55544 {for} should be able to init array elements 2015-05-18 04:00:17 +02:00
Uwe Tews e3123c0427 - improvement higher compilation speed by modified lexer/parser generator at "smarty/smarty-lexer" 2015-05-16 16:33:50 +02:00
Uwe Tews d21921de22 - improvement reduce number of lexer tokens on operators and if conditions 2015-05-16 14:47:12 +02:00
Uwe Tews 22bccee350 - improvement remove not needed ?><?php transitions from compiled code 2015-05-16 14:17:59 +02:00
Uwe Tews 0bdd805d6b remove code not intended for this version 2015-05-16 13:40:45 +02:00
Uwe Tews a74804b061 - bugfix {php}{/php} did work just for single lines https://github.com/smarty-php/smarty/issues/33 2015-05-16 13:33:04 +02:00
Uwe Tews 9f1061f5bc - bugfix template functions failed when calling the function recursively with function name as tag name https://github.com/smarty-php/smarty/issues/28 2015-05-14 15:13:09 +02:00
Uwe Tews 2db464a6e5 - bugfix template functions failed when calling the function recursively with function name as tag name https://github.com/smarty-php/smarty/issues/28 2015-05-14 15:11:38 +02:00
Uwe Tews 8ee805632d - bugfix in Smarty_Security 'nl2br' should be a trusted modifier, not PHP function (code.google issue 223) 2015-05-13 20:17:02 +02:00
Uwe Tews dea56a2243 default for $debug_tpl will be set up in Smarty_Internal_Debug 2015-05-13 19:25:05 +02:00
Uwe Tews e0dbc79204 Debugging - add display of Smarty version 2015-05-13 19:10:06 +02:00
Uwe Tews a3c89bb4f4 Debugging - truncate output of Origin to 80 characters and increase string values from 40 to 80 characters 2015-05-13 19:03:54 +02:00
Uwe Tews 319e396937 use clean Smarty object to display the debugging console.
Avoid possible promblems when application did overload the Smarty object or properties go modified hardcoded in the class source.
2015-05-13 18:04:29 +02:00
Uwe Tews 3240b5a596 - improvement remove not needed ?><?php transitions from compiled code 2015-05-13 02:09:00 +02:00
Uwe Tews 2b858212b7 - improvement remove not needed ?><?php transitions from compiled code 2015-05-13 02:06:33 +02:00
Uwe Tews cf5b5c4e1f Disable hhvm test because of a hhvm PHP compatibility problem 2015-05-13 01:50:23 +02:00
Uwe Tews 07c781d9cf - bugfix in nested {foreach} saved item attributes got overwritten https://github.com/smarty-php/smarty/issues/33 2015-05-13 00:33:23 +02:00
Uwe Tews e4741e9dd7 version update after fixed issues 28 and 29 2015-05-12 20:41:41 +02:00
Uwe Tews ece0e2241f Log fixes for issue 28 and 29 2015-05-12 20:39:10 +02:00
Uwe Tews 3ac71869a6 Remove PHP nightly test 2015-05-12 20:33:18 +02:00
uwetews f791eeba11 Merge pull request #32 from Stricted/patch-1
fix variable name
2015-05-12 18:40:53 +02:00
uwetews 962cf3d193 Merge pull request #30 from Stricted/master
fix constant handling
2015-05-12 18:40:08 +02:00
Stricted a8f30dc7f6 fix variable name 2015-05-12 15:52:54 +02:00
Stricted 4af23bc104 fix last commit 2015-05-12 15:44:54 +02:00
Stricted 811e2e0e13 fix constant handling
on undefined constants you get 'TEST_CONST' on definied constants TEST_CONST
2015-05-12 15:43:57 +02:00
Uwe Tews 2ff51de3df allow failures of hhvm 2015-05-12 04:48:10 +02:00
Uwe Tews 04f0090c40 release 3.1.23 2015-05-12 04:08:22 +02:00
Uwe Tews e6a4e68139 remove hhvm nightly test 2015-05-12 04:01:10 +02:00
Uwe Tews d234625d7c - bugfix of smaller performance issue introduce in 3.1.22 when caching is enabled 2015-05-12 03:34:38 +02:00
Uwe Tews b4792df08a - bugfix missig entry for smarty-temmplate-config in autoloader 2015-05-12 03:07:24 +02:00
Uwe Tews 6deb3cee7c update travis 2015-05-12 02:58:32 +02:00
Uwe Tews c12655ded2 - bugfix of smaller performance issue introduce in 3.1.22 when caching is enabled 2015-05-12 02:52:30 +02:00
Uwe Tews 8acb920e20 update 2015-05-12 01:17:14 +02:00
Uwe Tews d276829aa6 fix comment 2015-05-11 23:09:27 +02:00
Uwe Tews 556185c9e2 Update 2015-05-10 23:17:43 +02:00
Uwe Tews ebef3b1988 Update 2015-05-10 23:14:51 +02:00
Uwe Tews ee8a695a57 Update 2015-05-10 22:46:48 +02:00
Uwe Tews 94d5e1e198 Update 2015-05-10 22:42:24 +02:00
Uwe Tews 469a6ad860 correction 2015-05-10 21:55:43 +02:00
Uwe Tews 735507b0ba correction 2015-05-10 21:53:16 +02:00
Uwe Tews 4c3e67a301 update 2015-05-10 21:47:34 +02:00
Uwe Tews 31edf7fcea push 2015-05-10 21:44:18 +02:00
Uwe Tews 5963632a99 add .travis.yml 2015-05-10 21:05:54 +02:00
Uwe Tews 3836cafd90 Prepare 3.1.23-dev 2015-05-10 13:17:33 +02:00
Uwe Tews 0f9ec2642a Release 3.1.22 2015-05-10 13:08:04 +02:00
Uwe Tews ab93b0feee - improvement added constants for $debugging 2015-05-10 12:18:41 +02:00
Uwe Tews 741a07fc8f new dev version 2015-05-10 12:13:21 +02:00
Uwe Tews 8a34ad0cd2 parameter cleanup 2015-05-10 12:09:24 +02:00
Uwe Tews b0ca67b213 - bugfix cache lock was not handled correctly after timeout when $cache_locking == true 2015-05-10 12:08:47 +02:00
Uwe Tews 5ce5d4df49 - bugfix custom cache resource did not observe compile_id and cache_id when $cache_locking == true 2015-05-10 12:00:19 +02:00
Uwe Tews edf49ca3cf formatting 2015-05-10 11:53:09 +02:00
Uwe Tews af4a923da5 - uodate and fixes at cache locking 2015-05-08 07:27:45 +02:00
Uwe Tews d7b0b57420 - optimization of resource class loading 2015-05-08 06:02:59 +02:00
Uwe Tews c5468b421e - optimization of resource class loading 2015-05-07 22:57:59 +02:00
Uwe Tews 37449b2fcb - improvement of the debugging console. Read NEW_FEATURES.txt 2015-05-07 04:36:49 +02:00
Uwe Tews af08353e93 - bugfix/improvement in 3.1.22-dev cache locking did not work as expected 2015-05-06 23:10:39 +02:00
Uwe Tews 57df382ff2 - bugfix in 3.1.22-dev cache resource must not be loaded for subtemplates 2015-05-06 22:10:04 +02:00
Uwe Tews d92714cc7e - optimization move <?php ?> handling from parser to new compiler module 2015-05-06 00:03:26 +02:00
Uwe Tews d7ff1eec47 - optimization on cache update when main template is modified 2015-05-05 15:46:24 +02:00
Uwe Tews 914815d438 Fix broken code 2015-05-05 06:48:37 +02:00
Uwe Tews 3e4734acfb - bugfix code could be messed up when {tags} are used in multiple attributes https://github.com/smarty-php/smarty/issues/23 2015-05-05 03:33:53 +02:00
Uwe Tews 6575e11f68 Add missing properties 2015-05-05 03:27:16 +02:00
Uwe Tews c5915a8c0c - improvement use is_file() checks to avoid errors suppressed by @ which could still cause problems (https://github.com/smarty-php/smarty/issues/24) 2015-05-05 00:41:30 +02:00
Uwe Tews f14f2dcc6f - bugfix Smarty_Resource::parseResourceName incompatible with Google AppEngine (https://github.com/smarty-php/smarty/issues/22) 2015-05-04 22:44:29 +02:00
Uwe Tews 22ea1404df add information how to get development tools 2015-05-04 18:21:55 +02:00
Uwe Tews 08c81acbb1 add require-dev to load PHPUnit tests and lxer/parser generator (reverted from commit f3d7b05ccb) 2015-05-04 18:20:44 +02:00
Uwe Tews 9789867d8b Revert "add require-dev to load PHPUnit tests and lxer/parser generator"
This reverts commit f3d7b05ccb.
2015-05-04 18:09:21 +02:00
Uwe Tews 80926a538d Revert "test"
This reverts commit d40e2a0286.
2015-05-04 18:08:41 +02:00
Uwe Tews d40e2a0286 test 2015-05-04 05:54:05 +02:00
Uwe Tews f3d7b05ccb add require-dev to load PHPUnit tests and lxer/parser generator 2015-05-04 05:20:22 +02:00
Uwe Tews ea17aad266 - bugfix plugins of merged subtemplates not loaded in 3.1.22-dev (forum topic 25508) 2nd fix 2015-04-28 23:12:12 +02:00
Uwe Tews e312dd9b59 - bugfix plugins of merged subtemplates not loaded in 3.1.22-dev (forum topic 25508) 2015-04-28 01:38:45 +02:00
Uwe Tews c7ba22dc98 - bugfix a nocache template variable used as parameter at {insert} was by mistake cached 2015-04-23 02:34:28 +02:00
Uwe Tews de892651c2 - bugfix at a template function containing nocache code a parmeter could overwrite a template variable of same name 2015-04-20 22:59:45 +02:00
Uwe Tews 6fb27d5ae4 strip property must now be public 2015-04-07 02:11:20 +02:00
Uwe Tews a92302d059 move strip processing from parser to compiler 2015-04-02 01:42:53 +02:00
Uwe Tews e9fd2354ef move compileVariable() from parser to compiler 2015-04-02 01:35:16 +02:00
Uwe Tews ea2a566b1f - bugfix Smarty_Security->allow_constants=false; did also disable true, false and null (change of 16.03.2015)
- improvement added a whitelist for trusted constants to security Smarty_Security::$trusted_constants (forum topic 25471)
2015-03-28 03:58:08 +01:00
Uwe Tews 443ae8c216 - bugfix problems when {function}{/function} defined a template function in a cached subtemplate and it was called {call} from a not cached subtemplate {forum topic 25468} 2015-03-23 00:39:22 +01:00
Uwe Tews 2a005ac6d6 - bugfix correct update of global variable values on exit of template functions. (reported under Smarty Developers) 2015-03-20 18:25:59 +01:00
Uwe Tews 2758cb8ce9 Correct version number 2015-03-20 01:49:52 +01:00
Uwe Tews 4ecc75344f - bugfix make sure that function properties get saved only in compiled files containing the fuction definition {forum topic 25452} 2015-03-20 00:41:55 +01:00
Uwe Tews 03c7b786a0 Clean up template functions property structure 2015-03-17 04:53:57 +01:00
Uwe Tews ab1272a2e4 fix whitespaces on tags included in double quoted strings 2015-03-17 04:31:51 +01:00
Uwe Tews 4c0e124c22 - bugfix {block}{/block} tags did not work inside double quoted strings issues #18 2015-03-17 03:40:01 +01:00
Uwe Tews 6df84b6fe3 - bugfix {block}{/block} tags did not work inside double quoted issues #18 2015-03-17 03:31:44 +01:00
Uwe Tews e7ad5909e5 - bugfix Smarty_Security->allow_constants=false; did not disallow direct usage of defined constants like {SMARTY_DIR} {forum topic 25457} 2015-03-17 02:29:19 +01:00
Uwe Tews eead9c81e9 - bugfix problems with {function}{/function} and {call} tags in different subtemplate cache files {forum topic 25452} 2015-03-17 01:10:51 +01:00
Uwe Tews 7b7118eea9 - bugfix $smarty->compile_check must be restored before rendering of a just updated cache file {forum 25452} 2015-03-15 02:01:07 +01:00
Uwe Tews 7fe81e6d79 - bugfix {nocache} {/nocache} tags corrupted code when used within a nocache section caused by a nocache template variable 2015-03-14 15:17:58 +01:00
Uwe Tews 8020144d46 - bugfix template functions defined with {function} in an included subtemplate could not be called in nocache
mode with {call... nocache} if the subtemplate had it's own cache file {forum 25452}
2015-03-14 12:02:57 +01:00
Uwe Tews e9b1f296cb - bugfix {include ... nocache} with variable file or compile_id attribute was not executed in nocache mode. 2015-03-10 18:06:05 +01:00
Uwe Tews 8892f358ad - bugfix __get() was called when loading config files 2015-03-07 01:44:30 +01:00
Uwe Tews b1cd4cd7d2 Return to saved output buffer level on exceptions 2015-03-01 21:39:54 +01:00
Uwe Tews 464b37c053 optimize compiled code of {foreach} 2015-02-15 16:58:42 +01:00
Uwe Tews 8082bc7471 get rid of smarty object self pointer 2015-02-15 01:45:37 +01:00
Uwe Tews f93cfc63ad get rid of reference parameter 2015-02-14 21:57:42 +01:00
Uwe Tews 6925c98af0 - bugfix multiple Smarty::fetch() of same template when $smarty->merge_compiled_includes = true; could cause function alreday defined error 2015-02-12 23:56:43 +01:00
Uwe Tews 0e87a99507 - bugfix recursive {includes} did create E_NOTICE message when $smarty->$merge_compiled_includes = true; 2015-02-11 07:15:40 +01:00
Uwe Tews aec380839c - bugfix recursive {includes} did create E_NOTICE message when $smarty->$merge_compiled_includes = true; 2015-02-11 06:57:17 +01:00
Uwe Tews 05f5ddf573 remove comments 2015-02-09 23:52:25 +01:00
Uwe Tews d62d394345 update 2015-02-08 22:22:52 +01:00
Uwe Tews d288e58692 update 2015-02-08 21:36:32 +01:00
Uwe Tews b2b114d5b8 udate 2015-02-08 21:21:30 +01:00
Uwe Tews 10bf6f6032 add isset($_smarty_tpl) to avoid errors when unit test runs in separate process 2015-02-08 21:10:45 +01:00
Uwe Tews 1fc2b9ece2 add isset($_smarty_tpl) to avoid errors when unit test runs in separate process 2015-02-08 19:57:14 +01:00
Uwe Tews e4e3e176c0 add note 2015-01-22 04:07:58 +01:00
Uwe Tews 1a781b39b1 new feature: security can now control access to static methods and properties
see also NEW_FEATURES.txt
2015-01-22 03:53:01 +01:00
Uwe Tews ec19bc763f - bugfix 'self::' and 'parent::' was interpreted in template syntax as static class 2015-01-21 23:30:37 +01:00
Uwe Tews 8d5fa36a80 - bugfix clearCompiledTemplates(), clearAll() and clear() could try to delete whole drive
at wrong path permissions because realpath() fail (forum 25397)
2015-01-21 22:14:25 +01:00
Uwe Tews 85f24ce413 convert writeFile() to object method to remove a vulnerability 2015-01-21 21:12:00 +01:00
Uwe Tews 7a1df12afa - bugfix clearCompiledTemplates() could try to delete whole drive
at wrong path permissions because realpath() fail (forum 25397)
2015-01-20 22:33:38 +01:00
Uwe Tews 4428d72e6d Update testInstall() and move it into its own class 2015-01-12 22:12:20 +01:00
Uwe Tews 593f984f6a load source, compiled and cache resource manually in normal flow (avoid __get()) 2015-01-07 17:46:12 +01:00
Uwe Tews 466c3ee9f8 Use require_once ; remove unnedded paramter 2015-01-07 16:46:57 +01:00
Uwe Tews 740a583c7c Use require_once 2015-01-07 16:46:03 +01:00
Uwe Tews b3f8ddefd2 remove redundant overloaded methods 2015-01-06 04:42:49 +01:00
Uwe Tews 43f043364f fix case in class name 2015-01-06 01:18:58 +01:00
Uwe Tews 67162324bb check ..._dir property overloading
if $template_dir, $compile_dir, $cache_dir, $config_dir or $plugins_dir properties
are overloaded the setters must be called for required processing
2015-01-05 02:03:24 +01:00
Uwe Tews 2aaa29ad20 reset _is_file_cache 2015-01-04 23:54:11 +01:00
Uwe Tews 7cc981e6a6 revert some unneeded normalization of compiled_dir, cache_dir and plugins_dir 2015-01-04 23:42:22 +01:00
Uwe Tews 3463fae2a1 push llast weeks changes to github 2015-01-04 05:57:49 +01:00
Uwe Tews 111a10bb17 Move some classes into its own files 2015-01-04 05:51:52 +01:00
Uwe Tews d528234a97 Small optimization 2015-01-04 05:51:03 +01:00
Uwe Tews 068da64c99 best defaults for internal resource caching
$resource_caching = false and $template_resource_caching = true

fixed typos
2015-01-04 05:49:38 +01:00
Uwe Tews 66eac7bc2a fix code frame of inline (merged) subtemplate 2015-01-03 21:32:33 +01:00
Uwe Tews 8b71e591c0 some minor speed optimization 2015-01-03 21:27:33 +01:00
Uwe Tews 57620443e9 Optimize constructor 2015-01-03 07:56:03 +01:00
Uwe Tews f236905fed create different compiled templates and config files
Smarty does now automatically detect a change of the $merge_compiled_includes and $escape_html
    property and create different compiled templates files depending on the setting.

    Same applies to config files and the $config_overwrite, $config_booleanize and
    $config_read_hidden properties.
2015-01-03 07:36:07 +01:00
Uwe Tews cfdd53c6b4 restructure config file processing
move code into an extension class
use Smarty_Internal_Template
2015-01-02 22:30:53 +01:00
Uwe Tews 75ad0b4da5 move default template handling into an extesion class 2015-01-02 10:48:07 +01:00
Uwe Tews 15728f6ea3 normalize directory path 2015-01-02 10:22:36 +01:00
Uwe Tews c8712b8b7e update autoloader 2015-01-02 09:12:27 +01:00
Uwe Tews 0a3579f9ca restructure template processing
Code was moved into classes it better belongs to.
This does reduce also Smarty's memory footprint
2015-01-02 09:12:01 +01:00
Uwe Tews 8c1f400c09 remove \r from template source before compiling 2015-01-02 08:25:27 +01:00
Uwe Tews 97e7948e16 fix update of file dependency 2015-01-02 08:20:57 +01:00
Uwe Tews 6f801de283 update buildFilepath() 2015-01-02 06:29:08 +01:00
Uwe Tews c55367d1f6 update buildFilepath() 2015-01-02 06:26:04 +01:00
Uwe Tews 296a88b557 Change class name case because of composer autoloader problems 2015-01-02 06:07:19 +01:00
Uwe Tews 3f08b18170 Correct recompiled check 2015-01-02 01:05:03 +01:00
Uwe Tews 48f66c81c7 rework class Smarty_Template_Cached
- move class Smarty_Template_Cached in its own file
- implement all code for chached template handling in class
2015-01-01 23:53:59 +01:00
Uwe Tews c3aa9994c8 rework source resource handling
- move class Smarty_Template_Source into its own file
- impelement all source processing into the classes it better belongs to
2015-01-01 23:34:29 +01:00
Uwe Tews dd2d24d1d6 rework class Smarty_Template_Compiled
- move class Smarty_Template_Compiled in its own file
- implement all code for compiled template handling in class
2015-01-01 23:28:09 +01:00
Uwe Tews 7c4e5175a4 rework class Smarty_Template_Compiled
- move class Smarty_Template_Compiled in its own file
- implement all code for compiled template handling in class (reverted from commit f6a1349fdb)
2015-01-01 23:15:08 +01:00
Uwe Tews f6a1349fdb rework class Smarty_Template_Compiled
- move class Smarty_Template_Compiled in its own file
- implement all code for compiled template handling in class
2015-01-01 23:11:35 +01:00
Uwe Tews 80bf76cc6e move internal createTemplateCodeFrame() method into an extension class 2015-01-01 22:59:07 +01:00
Uwe Tews e8a77171d3 implement templateId generation as method 2015-01-01 22:27:45 +01:00
Uwe Tews 2f8d4f1dbf missing property 2014-12-31 16:08:36 +01:00
Uwe Tews 0cb8b24055 implement most common stetters as method for better performance 2014-12-31 15:56:59 +01:00
Uwe Tews b013984dfd move properties into classes where they better belong to 2014-12-31 15:44:08 +01:00
Uwe Tews 2687f36849 update autoloader with for special class names 2014-12-31 14:32:47 +01:00
Uwe Tews 47faa63a0e use function_exists('mb_get_info') for setting Smarty::$_MBSTRING
Function mb_split could be overloaded depending on php.ini mbstring.func_overload
2014-12-31 06:07:17 +01:00
Uwe Tews 4b7fba4d88 get config properties via compiler object
- reverting part of earlier change of today
2014-12-30 18:16:51 +01:00
Uwe Tews e351c0123f move some code into Smarty_Internal_Debug class
where it better belongs to
2014-12-30 17:17:15 +01:00
Uwe Tews d3e26fb679 template function call handling 2014-12-30 16:43:42 +01:00
Uwe Tews 1d248d6349 formatting 2014-12-30 16:28:18 +01:00
Uwe Tews 8fe6f14af7 Change class name case because of composer autoloader problems 2014-12-30 16:27:08 +01:00
Uwe Tews b122878131 rename parse tree class names and minor fixes 2014-12-30 16:22:03 +01:00
Uwe Tews 825ccc9f47 rename parse tree class names to Smarty_Internal_ParseTree.... 2014-12-30 16:16:54 +01:00
Uwe Tews 485f093e0b get config properties via template object 2014-12-30 16:03:21 +01:00
Uwe Tews 6be6bf7b70 limit the template nesting level by security 2014-12-30 12:57:43 +01:00
Uwe Tews 1da50aa61d security can now disable special $smarty variables
see also NEW_FEATURES.txt
2014-12-29 21:59:23 +01:00
Uwe Tews 49a3427515 clear internal _is_file_cache when plugins_dir was modified 2014-12-27 23:06:04 +01:00
Uwe Tews 5e4f55d121 add .plex and .y files
add lexer .plex and parser .y files to distribution for easier version
control
2014-12-14 00:49:42 +01:00
Uwe Tews 46654268ef update .gitignore 2014-12-14 00:44:11 +01:00
Uwe Tews 2fb5bc6bbe lexer and parser optimizations
up to 30% higher compiling speed depending on template complexity
2014-12-13 23:02:29 +01:00
Uwe Tews 2fe60e8996 resolve parser ambiguity
- bugfix resolve parser ambiguity between constant print tag {CONST} and
other smarty tags after change of 09.12.2014
2014-12-11 05:21:21 +01:00
Smarty PHP Template Engine 042e93c725 Merge pull request #12 from jenolan/master
Commit 7b2a2c4a88 changed the constant pro...
2014-12-11 03:11:19 +01:00
Larry Lewis 7bb7b3ac03 Commit 7b2a2c4a88 changed the constant processing to allow a variable in teh $smarty.const but this broke the normal callout. Change allows both methods. 2014-12-11 08:06:27 +11:00
Uwe Tews 2a2a73cabc - bugfix call of template function by a variable name
did not work after latest changes (forum 25342)
2014-12-10 00:51:09 +01:00
Uwe Tews 7bd40d2c0b - bugfix variables $null, $true and $false did not work
after the change of 12.11.2014 (forum 25342)
2014-12-09 23:33:11 +01:00
Uwe Tews ffbfe40043 - bugfix a plugin with attached modifier could fail
if the tag was immediately followed by another Smarty tag (since 3.1.21) (forum 25326)
2014-11-23 13:25:09 +01:00
Uwe Tews de7310b702 Revert "delete unwanted file"
This reverts commit 77d8349ffb.
2014-11-13 19:52:41 +01:00
Uwe Tews 77d8349ffb delete unwanted file 2014-11-13 19:48:34 +01:00
Uwe Tews 0b6af0add7 move autoload code into Autoloader.php.
Use Composer autoloader when possible
2014-11-13 19:42:01 +01:00
Uwe Tews 0b21213c55 new feature - added support of namespaces to template code 2014-11-12 19:07:00 +01:00
Uwe Tews c7e8881c76 bugfix for recent changes of {function} tag handling 2014-11-11 01:01:01 +01:00
Uwe Tews 9ecbb93ebb update of the $smarty->merge_compiled_includes option 2014-11-11 00:03:08 +01:00
Uwe Tews 460be5a5da bugfix for recent changes of {function} tag handling 2014-11-10 23:57:30 +01:00
Uwe Tews adc6091c4d update of cache resources for template function calls in nocache mode 2014-11-09 10:20:06 +01:00
Uwe Tews 223cdc0787 moved code into constructor 2014-11-09 10:15:16 +01:00
Uwe Tews 230c5787e6 move Smarty exceptions into syslibs folder 2014-11-09 06:42:20 +01:00
Uwe Tews 4edb5fce30 Update of change log 2014-11-08 21:44:55 +01:00
Uwe Tews b82756a705 - bugfix subtemplate called in nocache mode could be called with wrong compile_id when it did change on one of the calling templates 2014-11-08 21:27:53 +01:00
Uwe Tews ea9c681106 remove no longer needed code 2014-11-08 21:06:53 +01:00
Uwe Tews f92af96419 fixed $smarty->debugging on merged compiled subtemplates 2014-11-08 21:02:14 +01:00
Uwe Tews 8f8d462b8a add code of template functions called in nocache mode dynamically to cache file 2014-11-08 17:19:53 +01:00
uwetews 845c4184b2 Merge pull request #9 from uwetews/master
new $smarty->debug options
2014-11-04 19:00:56 +01:00
Uwe Tews 963e5dae5e new $smarty->debug options
- new feature $smarty->debug = true; => overwrite existing Debug Console
window (old behaviour)
$smarty->debug = 2; => individual Debug Console window by template name
2014-11-04 18:59:57 +01:00
uwetews 5b1c649c6a Merge pull request #8 from uwetews/master
Debug Console Update
2014-11-03 22:31:13 +01:00
Uwe Tews 158b7be58a Debug Console Update
- bugfix Debug Console did not show included subtemplates since 3.1.17
(forum 25301)
- bugfix Modifier debug_print_var did not limit recursion or prevent
recursive object display at Debug Console
(ATTENTION: parameter order has changed to be able to specify maximum
recursion)
- bugfix Debug consol did not include subtemplate information with
$smarty->merge_compiled_includes = true
- improvement The template variables are no longer displayed as objects
on the Debug Console
- improvement $smarty->createData($parent = null, $name = null) new
optional name parameter for display at Debug Console
- addition of some hooks for future extension of Debug Console
2014-11-03 22:27:32 +01:00
uwetews 4b3196fe30 Merge pull request #2 from smarty-php/master
Merge pull request #7 from uwetews/master
2014-11-02 14:57:41 +01:00
uwetews 4369b2fe05 Merge pull request #7 from uwetews/master
-bugfix and enhancement on subtemplate {include} and template {function}
2014-11-01 22:52:01 +01:00
Uwe Tews bc13ebbc9b -bugfix and enhancement on subtemplate {include} and template {function} tags.
* Calling a template which has a nocache section could fail if it was
called from a cached and a not cached subtemplate.
* Calling the same subtemplate cached and not cached with the
$smarty->merge_compiled_includes enabled could cause problems
* Many smaller related changes
2014-11-01 22:42:34 +01:00
uwetews 5f2f292739 Merge pull request #1 from smarty-php/master
merge
2014-11-01 11:24:58 +01:00
Smarty PHP Template Engine 337ab5bd1e Merge pull request #6 from aivus/patch-1
Clean merge conflicts
2014-11-01 11:14:25 +01:00
Ilya Antipenko 95cc39deb6 Clean merge conflicts 2014-11-01 11:22:03 +02:00
Smarty PHP Template Engine 402547baaf Merge pull request #5 from uwetews/master
resolved merge conflict
2014-11-01 00:42:31 +01:00
Uwe Tews 199c16e827 resolved merge conflict 2014-11-01 00:34:32 +01:00
Uwe Tews 84e5ef7345 3.1.22-dev 2014-10-31 05:48:52 +01:00
Uwe Tews 21204c6613 Merge branch 'trunk' 2014-10-31 05:31:56 +01:00
Uwe Tews 52fb7b1e25 - bugfix access to class constant by object like {$object::CONST} or variable class name {$class::CONST} did not work (forum 25301) me 2014-10-30 00:55:01 +01:00
Uwe Tews 0c9ca2994e - bugfix merge_compiled_includes option failed when caching enables and same subtemplate was included cached and not cached 2014-10-26 09:47:10 +01:00
Uwe Tews f7955513b2 Revert "- bugfix template function call handler must never be called as nocache code"
This reverts commit db183d1aa4.
2014-10-24 00:09:45 +02:00
Uwe Tews db183d1aa4 - bugfix template function call handler must never be called as nocache code 2014-10-23 19:05:25 +02:00
Uwe Tews a22ee9f264 - bugfix E_NOTICE message was created during compilation when ASP tags '<%' or '%>' are in template source text 2014-10-23 18:27:12 +02:00
Uwe Tews fc55a39d67 Update README.md 2014-10-23 18:13:05 +02:00
Uwe Tews 53c5e3fc4a Added licence file and demo folder 2014-10-18 17:42:52 +02:00
Uwe Tews cbc9ce927e add composer release notes 2014-10-18 07:48:57 +02:00
Uwe Tews c0a9a0449b add composer release notes 2014-10-18 07:44:20 +02:00
Uwe Tews 16afbfaca1 Prepare 3.1.22-dev 2014-10-18 01:21:53 +02:00
Uwe Tews 1441f32fce Upload 3.1.21 2014-10-18 01:19:29 +02:00
Uwe Tews 117d28f647 Upload 3.21 2014-10-18 01:17:22 +02:00
Uwe Tews 542892dded Upload 3.1.21 2014-10-18 01:09:18 +02:00
Uwe Tews 024b336bea Upload 3.1.20 2014-10-18 01:05:22 +02:00
Uwe Tews 7c6b3d21fa revert 2014-10-18 01:01:36 +02:00
Uwe Tews 6cb40b8bcc Upload 3.1.20 2014-10-18 00:55:00 +02:00
Uwe Tews bdac1cb2e1 Upload 3.1.20 2014-10-18 00:53:39 +02:00
Uwe Tews d26db3f717 Revert "Prepare 3.2.22-dev"
This reverts commit 451c62001d.
2014-10-18 00:45:38 +02:00
Uwe Tews 451c62001d Prepare 3.2.22-dev 2014-10-18 00:38:59 +02:00
Uwe Tews eb48f3bcea Upload 3.1.21 2014-10-18 00:31:50 +02:00
Uwe Tews 0409ab005e Upload version 3.1.20 2014-10-18 00:18:11 +02:00
uwetews d091179e43 Initial commit 2014-10-17 19:51:33 +02:00
179 changed files with 19265 additions and 12753 deletions
+22
View File
@@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
+221
View File
@@ -0,0 +1,221 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#############
## Windows detritus
#############
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
.idea/
# Smarty
lexer/*.php
lexer/*.out
+25
View File
@@ -0,0 +1,25 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
matrix:
allow_failures:
- php: hhvm
before_script:
- travis_retry composer self-update
- travis_retry composer --prefer-source --dev install
install:
- git clone --depth=50 --branch=master git://github.com/smarty-php/smarty-phpunit.git
script:
- cd smarty-phpunit
- phpunit ./
+29
View File
@@ -0,0 +1,29 @@
Starting with Smarty 3.1.21 Composer has been configured to load the packages from github.
*******************************************************************************
* *
* NOTE: Because of this change you must clear your local composer cache with *
* the "composer clearcache" command *
* *
*******************************************************************************
To get the latest stable version use
"require": {
"smarty/smarty": "~3.1"
}
in your composer.json file.
To get the trunk version use
"require": {
"smarty/smarty": "~3.1@dev"
}
The "smarty/smarty" package will start at libs/.... subfolder.
To retrieve the development and documentation folders add
"require-dev": {
"smarty/smarty-dev": "~3.1@dev"
}
+37 -5
View File
@@ -1,4 +1,40 @@
In Smarty 3.1 template inheritance is a compile time process. All the extending of {block} tags
Starting with version 3.1.28 template inheritance is no longer a compile time process.
All {block} tag parent/child relations are resolved at run time.
This does resolve all known existing restrictions (see below).
The $smarty::$inheritance_merge_compiled_includes property has been removed.
Any access to it is ignored.
This does enable some new features:
Any code outside root {block} tags in child templates is now executed but any output will be ignored.
{extends 'foo.tpl'}
{$bar = 'on'} // assigns variable $bar seen in parent templates
{block 'buh'}{/block}
{extends 'foo.tpl'}
{$bar} // the output of variable bar is ignored
{block 'buh'}{/block}
{block} tags can be dynamically en/disabled by conditions.
{block 'root'}
{if $foo}
{block 'v1'}
....
{/block}
{else}
{block 'v1'}
....
{/block}
{/if}
{/block}
THE FOLLOWING RESTRICTIONS ARE NO LONGER EXISTING:
In Smarty 3.1 template inheritance is a compile time process. All the extending of {block} tags
is done at compile time and the parent and child templates are compiled in a single compiled template.
{include} subtemplate could also {block} tags. Such subtemplate could not compiled by it's own because
it could be used in other context where the {block} extended with a different result. For that reasion
@@ -29,7 +65,3 @@ You must now manually merge all {include} subtemplate which do contain {block} t
3. If call templates with different template_dir configurations and a parent could same named child template from different folders
you must make the folder name part of the compile_id.
In the upcomming major release Smarty 3.2 inheritance will no longer be a compile time process.
All restrictions will be then removed.
+133
View File
@@ -0,0 +1,133 @@
This file contains a brief description of new features which have been added to Smarty 3.1
Smarty 3.1.28
OPCACHE
=======
Smarty does now invalidate automatically updated and cleared compiled or cached template files in OPCACHE.
Correct operation is no longer dependent on OPCACHE configuration settings.
Template inheritance
====================
Template inheritance is now processed in run time.
See the INHERITANCE_RELEASE_NOTES
Modifier regex_replace
======================
An optional limit parameter was added
fetch() and display()
=====================
The fetch() and display() methods of the template object accept now optionally the same parameter
as the corresponding Smarty methods to get tne content of another template.
Example:
$template->display(); Does display template of template object
$template->dispaly('foo.tpl'); Does display template 'foo.bar'
File: resource
==============
Multiple template_dir entries can now be selected by a comma separated list of indices.
The template_dir array is searched in the order of the indices. (Could be used to change the default search order)
Example:
$smarty->display([1],[0]foo.bar');
Filter support
==============
Optional filter names
An optional filter name was added to $smarty->registerFilter(). It can be used to unregister a filter by name.
- $smarty->registerFilter('output', $callback, 'name');
$smarty->unregister('output', 'name');
Closures
$smarty->registerFilter() does now accept closures.
- $smarty->registerFilter('pre', function($source) {return $source;});
If no optional filter name was specified it gets the default name 'closure'.
If you register multiple closures register each with a unique filter name.
- $smarty->registerFilter('pre', function($source) {return $source;}, 'closure_1');
- $smarty->registerFilter('pre', function($source) {return $source;}, 'closure_2');
Smarty 3.1.22
Namespace support within templates
==================================
Within templates you can now use namespace specifications on:
- Constants like foo\bar\FOO
- Class names like foo\bar\Baz::FOO, foo\bar\Baz::$foo, foo\bar\Baz::foo()
- PHP function names like foo\bar\baz()
Security
========
- disable special $smarty variable -
The Smarty_Security class has the new property $disabled_special_smarty_vars.
It's an array which can be loaded with the $smarty special variable names like
'template_object', 'template', 'current_dir' and others which will be disabled.
Note: That this security check is performed at compile time.
- limit template nesting -
Property $max_template_nesting of Smarty_Security does set the maximum template nesting level.
The main template is level 1. The nesting level is checked at run time. When the maximum will be exceeded
an Exception will be thrown. The default setting is 0 which does disable this check.
- trusted static methods -
The Smarty_Security class has the new property $trusted_static_methods to restrict access to static methods.
It's an nested array of trusted class and method names.
Format:
array (
'class_1' => array('method_1', 'method_2'), // allowed methods
'class_2' => array(), // all methods of class allowed
)
To disable access for all methods of all classes set $trusted_static_methods = null;
The default value is an empty array() which does enables all methods of all classes, but for backward compatibility
the setting of $static_classes will be checked.
Note: That this security check is performed at compile time.
- trusted static properties -
The Smarty_Security class has the new property $trusted_static_properties to restrict access to static properties.
It's an nested array of trusted class and property names.
Format:
array (
'class_1' => array('prop_1', 'prop_2'), // allowed properties listed
'class_2' => array(), // all properties of class allowed
}
To disable access for all properties of all classes set $trusted_static_properties = null;
The default value is an empty array() which does enables all properties of all classes, but for backward compatibility
the setting of $static_classes will be checked.
Note: That this security check is performed at compile time.
- trusted constants .
The Smarty_Security class has the new property $trusted_constants to restrict access to constants.
It's an array of trusted constant names.
Format:
array (
'SMARTY_DIR' , // allowed constant
}
If the array is empty (default) the usage of constants can be controlled with the
Smarty_Security::$allow_constants property (default true)
Compiled Templates
==================
Smarty does now automatically detects a change of the $merge_compiled_includes and $escape_html
property and creates different compiled templates files depending on the setting.
Same applies to config files and the $config_overwrite, $config_booleanize and
$config_read_hidden properties.
Debugging
=========
The layout of the debug window has been changed for better readability
New class constants
Smarty::DEBUG_OFF
Smarty::DEBUG_ON
Smarty::DEBUG_INDIVIDUAL
have been introduced for setting the $debugging property.
Smarty::DEBUG_INDIVIDUAL will create for each display() and fetch() call an individual debug window.
.
+5 -4
View File
@@ -460,12 +460,13 @@ included template.
PLUGINS
=======
Smarty3 are following the same coding rules as in Smarty2.
The only difference is that the template object is passed as additional third parameter.
Smarty 3 plugins follow the same coding rules as in Smarty 2.
The main difference is that the template object is now passed in place of the smarty object.
The smarty object can be still be accessed through $template->smarty.
smarty_plugintype_name (array $params, object $smarty, object $template)
smarty_plugintype_name (array $params, Smarty_Internal_Template $template)
The Smarty 2 plugins are still compatible as long as they do not make use of specific Smarty2 internals.
The Smarty 2 plugins are still compatible as long as they do not make use of specific Smarty 2 internals.
TEMPLATE INHERITANCE:
+54 -17
View File
@@ -1,28 +1,65 @@
#Smarty 3 template engine
##Distribution repository
Starting with Smarty 3.1.21 Composer has been configured to load the packages from github.
**NOTE: Because of this change you must clear your local composer cache with the "composer clearcache" command**
To get the latest stable version use
> Smarty 3.1.28 introduces run time template inheritance
"require": {
"smarty/smarty": "~3.1"
}
> Read the NEW_FEATURES and INHERITANCE_RELEASE_NOTES file for recent extensions to Smarty 3.1 functionality
in your composer.json file.
To get the trunk version use
Smarty versions 3.1.11 or later are now on github and can be installed with Composer.
"require": {
"smarty/smarty": "~3.1@dev"
}
The "smarty/smarty" package will start at libs/.... subfolder.
To retrieve the development and documentation folders add
To get the latest stable version of Smarty 3.1 use
"require-dev": {
"smarty/smarty-dev": "~3.1@dev"
}
```json
"require": {
"smarty/smarty": "~3.1"
}
```
in your composer.json file.
To get the trunk version use
```json
"require": {
"smarty/smarty": "~3.1@dev"
}
```
For a specific version use something like
```json
"require": {
"smarty/smarty": "3.1.19"
}
```
PHPUnit test can be installed by corresponding composer entries like
```json
"require": {
"smarty/smarty-phpunit": "3.1.19"
}
```
Similar applies for the lexer/parser generator
```json
"require": {
"smarty/smarty-lexer": "3.1.19"
}
```
Or you could use
```json
"require": {
"smarty/smarty-dev": "3.1.19"
}
```
Which is a wrapper to install all 3 packages
Composer can also be used for Smarty2 versions 2.6.24 to 2.6.28
+421 -3
View File
@@ -1,10 +1,428 @@
===== 3.1.28 ===== (13.12.2015)
13.12.2015
- bugfix {foreach} and {section} with uppercase characters in name attribute did not work (forum topic 25819)
- bugfix $smarty->debugging_ctrl = 'URL' did not work (forum topic 25811)
- bugfix Debug Console could display incorrect data when using subtemplates
09.12.2015
- bugix Smarty did fail under PHP 7.0.0 with use_include_path = true;
09.12.2015
-bugfix {strip} should exclude some html tags from stripping, related to fix for https://github.com/smarty-php/smarty/issues/111
08.12.2015
- bugfix internal template function data got stored in wrong compiled file https://github.com/smarty-php/smarty/issues/114
05.12.2015
-bugfix {strip} should insert a single space https://github.com/smarty-php/smarty/issues/111
25.11.2015
-bugfix a left delimter like '[%' did fail on [%$var_[%$variable%]%] (forum topic 25798)
02.11.2015
- bugfix {include} with variable file name like {include file="foo_`$bar`.tpl"} did fail in 3.1.28-dev https://github.com/smarty-php/smarty/issues/102
01.11.2015
- update config file processing
31.10.2015
- bugfix add missing $trusted_dir property to SmartyBC class (forum topic 25751)
29.10.2015
- improve template scope handling
24.10.2015
- more optimizations of template processing
- bugfix Error when using {include} within {capture} https://github.com/smarty-php/smarty/issues/100
21.10.2015
- move some code into runtime extensions
18.10.2015
- optimize filepath normalization
- rework of template inheritance
- speed and size optimizations
- bugfix under HHVM temporary cache file must only be created when caches template was updated
- fix compiled code for new {block} assign attribute
- update code generated by template function call handler
18.09.2015
- bugfix {if $foo instanceof $bar} failed to compile if 2nd value is a variable https://github.com/smarty-php/smarty/issues/92
17.09.2015
- bugfix {foreach} first attribute was not correctly reset since commit 05a8fa2 of 02.08.2015 https://github.com/smarty-php/smarty/issues/90
16.09.2015
- update compiler by moving no longer needed properties, code optimizations and other
14.09.2015
- optimize autoloader
- optimize subtemplate handling
- update template inheritance processing
- move code of {call} processing back into Smarty_Internal_Template class
- improvement invalidate OPCACHE for cleared compiled and cached template files (forum topic 25557)
- bugfix unintended multiple debug windows (forum topic 25699)
30.08.2015
- size optimization move some runtime functions into extension
- optimize inline template processing
- optimization merge inheritance child and parent templates into one compiled template file
29.08.2015
- improvement convert template inheritance into runtime processing
- bugfix {$smarty.block.parent} did always reference the root parent block https://github.com/smarty-php/smarty/issues/68
23.08.2015
- introduce Smarty::$resource_cache_mode and cache template object of {include} inside loop
- load seldom used Smarty API methods dynamically to reduce memory footprint
- cache template object of {include} if same template is included several times
- convert debug console processing to object
- use output buffers for better performance and less memory usage
- optimize nocache hash processing
- remove not really needed properties
- optimize rendering
- move caching to Smarty::_cache
- remove properties with redundant content
- optimize Smarty::templateExists()
- optimize use_include_path processing
- relocate properties for size optimization
- remove redundant code
- bugfix compiling super globals like {$smarty.get.foo} did fail in the master branch https://github.com/smarty-php/smarty/issues/77
06.08.2015
- avoid possible circular object references caused by parser/lexer objects
- rewrite compileAll... utility methods
- commit several internal improvements
- bugfix Smarty failed when compile_id did contain "|"
03.08.2015
- rework clear cache methods
- bugfix compileAllConfig() was broken since 3.1.22 because of the changes in config file processing
- improve getIncludePath() to return directory if no file was given
02.08.2015
- optimization and code cleanup of {foreach} and {section} compiler
- rework {capture} compiler
01.08.2015
- update DateTime object can be instance of DateTimeImmutable since PHP5.5 https://github.com/smarty-php/smarty/pull/75
- improvement show resource type and start of template source instead of uid on eval: and string: resource (forum topic 25630)
31.07.2015
- optimize {foreach} and {section} compiler
29.07.2015
- optimize {section} compiler for speed and size of compiled code
28.07.2015
- update for PHP 7 compatibility
26.07.2015
- improvement impement workaround for HHVM PHP incompatibillity https://github.com/facebook/hhvm/issues/4797
25.07.2015
- bugfix parser did hang on text starting <?something https://github.com/smarty-php/smarty/issues/74
20.07.2015
- bugfix config files got recompiled on each request
- improvement invalidate PHP 5.5 opcache for recompiled and cached templates https://github.com/smarty-php/smarty/issues/72
12.07.2015
- optimize {extends} compilation
10.07.2015
- bugfix force file: resource in demo resource.extendsall.php
08.07.2015
- bugfix convert each word of class names to ucfirst in in compiler. (forum topic 25588)
07.07.2015
- improvement allow fetch() or display() called on a template object to get output from other template
like $template->fetch('foo.tpl') https://github.com/smarty-php/smarty/issues/70
- improvement Added $limit parameter to regex_replace modifier #71
- new feature multiple indices on file: resource
06.07.2015
- optimize {block} compilation
- optimization get rid of __get and __set in source object
01.07.2015
- optimize compile check handling
- update {foreach} compiler
- bugfix debugging console did not display string values containing \n, \r or \t correctly https://github.com/smarty-php/smarty/issues/66
- optimize source resources
28.06.2015
- move $smarty->enableSecurity() into Smarty_Security class
- optimize security isTrustedResourceDir()
- move auto load filter methods into extension
- move $smarty->getTemplateVars() into extension
- move getStreamVariable() into extension
- move $smarty->append() and $smarty->appendByRef() into extension
- optimize autoloader
- optimize file path normalization
- bugfix PATH_SEPARATOR was replaced by mistake in autoloader
- remove redundant code
27.06.2015
- bugfix resolve naming conflict between custom Smarty delimiter '<%' and PHP ASP tags https://github.com/smarty-php/smarty/issues/64
- update $smarty->_realpath for relative path not starting with './'
- update Smarty security with new realpath handling
- update {include_php} with new realpath handling
- move $smarty->loadPlugin() into extension
- minor compiler optimizations
- bugfix allow function plugins with name ending with 'close' https://github.com/smarty-php/smarty/issues/52
- rework of $smarty->clearCompiledTemplate() and move it to its own extension
19.06.2015
- improvement allow closures as callback at $smarty->registerFilter() https://github.com/smarty-php/smarty/issues/59
===== 3.1.27===== (18.06.2015)
18.06.2015
- bugfix another update on file path normalization failed on path containing something like "/.foo/" https://github.com/smarty-php/smarty/issues/56
===== 3.1.26===== (18.06.2015)
18.06.2015
- bugfix file path normalization failed on path containing something like "/.foo/" https://github.com/smarty-php/smarty/issues/56
17.06.2015
- bugfix calling a plugin with nocache option but no other attributes like {foo nocache} caused call to undefined function https://github.com/smarty-php/smarty/issues/55
===== 3.1.25===== (15.06.2015)
15.06.2015
- optimization of smarty_cachereource_keyvaluestore.php code
14.06.2015
- bugfix a relative sub template path could fail if template_dir path did contain /../ https://github.com/smarty-php/smarty/issues/50
- optimization rework of path normalization
- bugfix an output tag with variable, modifier followed by an operator like {$foo|modifier+1} did fail https://github.com/smarty-php/smarty/issues/53
13.06.2015
- bugfix a custom cache resource using smarty_cachereource_keyvaluestore.php did fail if php.ini mbstring.func_overload = 2 (forum topic 25568)
11.06.2015
- bugfix the lexer could hang on very large quoted strings (forum topic 25570)
08.06.2015
- bugfix using {$foo} as array index like $bar.{$foo} or in double quoted string like "some {$foo} thing" failed https://github.com/smarty-php/smarty/issues/49
04.06.2015
- bugfix possible error message on unset() while compiling {block} tags https://github.com/smarty-php/smarty/issues/46
01.06.2015
- bugfix <?xml ... ?> including template variables broken since 3.1.22 https://github.com/smarty-php/smarty/issues/47
27.05.2015
- bugfix {include} with variable file name must not create by default individual cache file (since 3.1.22) https://github.com/smarty-php/smarty/issues/43
24.05.2015
- bugfix if condition string 'neq' broken due to a typo https://github.com/smarty-php/smarty/issues/42
===== 3.1.24===== (23.05.2015)
23.05.2015
- improvement on php_handling to allow very large PHP sections, better error handling
- improvement allow extreme large comment sections (forum 25538)
21.05.2015
- bugfix broken PHP 5.2 compatibility when compiling <?php tags https://github.com/smarty-php/smarty/issues/40
- bugfix named {foreach} comparison like $smarty.foreach.foobar.index > 1 did compile into wrong code https://github.com/smarty-php/smarty/issues/41
19.05.2015
- bugfix compiler did overwrite existing variable value when setting the nocache attribute https://github.com/smarty-php/smarty/issues/39
- bugfix output filter trimwhitespace could run into the pcre.backtrack_limit on large output (code.google issue 220)
- bugfix compiler could run into the pcre.backtrack_limit on larger comment or {php} tag sections (forum 25538)
18.05.2015
- improvement introduce shortcuts in lexer/parser rules for most frequent terms for higher
compilation speed
16.05.2015
- bugfix {php}{/php} did work just for single lines https://github.com/smarty-php/smarty/issues/33
- improvement remove not needed ?><?php transitions from compiled code
- improvement reduce number of lexer tokens on operators and if conditions
- improvement higher compilation speed by modified lexer/parser generator at "smarty/smarty-lexer"
13.05.2015
- improvement remove not needed ?><?php transitions from compiled code
- improvement of debugging:
- use fresh Smarty object to display the debug console because of possible problems when the Smarty
was extended or Smarty properties had been modified in the class source
- display Smarty version number
- Truncate lenght of Origin display and extend strin value display to 80 character
- bugfix in Smarty_Security 'nl2br' should be a trusted modifier, not PHP function (code.google issue 223)
12.05.2015
- bugfix {$smarty.constant.TEST} did fail on undefined constant https://github.com/smarty-php/smarty/issues/28
- bugfix access to undefined config variable like {#undef#} did fail https://github.com/smarty-php/smarty/issues/29
- bugfix in nested {foreach} saved item attributes got overwritten https://github.com/smarty-php/smarty/issues/33
===== 3.1.23 ===== (12.05.2015)
12.05.2015
- bugfix of smaller performance issue introduce in 3.1.22 when caching is enabled
- bugfix missig entry for smarty-temmplate-config in autoloader
===== 3.1.22 ===== tag was deleted because 3.1.22 did fail caused by the missing entry for smarty-temmplate-config in autoloader
10.05.2015
- bugfix custom cache resource did not observe compile_id and cache_id when $cache_locking == true
- bugfix cache lock was not handled correctly after timeout when $cache_locking == true
- improvement added constants for $debugging
07.05.2015
- improvement of the debugging console. Read NEW_FEATURES.txt
- optimization of resource class loading
06.05.2015
- bugfix in 3.1.22-dev cache resource must not be loaded for subtemplates
- bugfix/improvement in 3.1.22-dev cache locking did not work as expected
05.05.2015
- optimization on cache update when main template is modified
- optimization move <?php ?> handling from parser to new compiler module
05.05.2015
- bugfix code could be messed up when {tags} are used in multiple attributes https://github.com/smarty-php/smarty/issues/23
04.05.2015
- bugfix Smarty_Resource::parseResourceName incompatible with Google AppEngine (https://github.com/smarty-php/smarty/issues/22)
- improvement use is_file() checks to avoid errors suppressed by @ which could still cause problems (https://github.com/smarty-php/smarty/issues/24)
28.04.2015
- bugfix plugins of merged subtemplates not loaded in 3.1.22-dev (forum topic 25508) 2nd fix
28.04.2015
- bugfix plugins of merged subtemplates not loaded in 3.1.22-dev (forum topic 25508)
23.04.2015
- bugfix a nocache template variable used as parameter at {insert} was by mistake cached
20.04.2015
- bugfix at a template function containing nocache code a parmeter could overwrite a template variable of same name
27.03.2015
- bugfix Smarty_Security->allow_constants=false; did also disable true, false and null (change of 16.03.2015)
- improvement added a whitelist for trusted constants to security Smarty_Security::$trusted_constants (forum topic 25471)
20.03.2015
- bugfix make sure that function properties get saved only in compiled files containing the fuction definition {forum topic 25452}
- bugfix correct update of global variable values on exit of template functions. (reported under Smarty Developers)
16.03.2015
- bugfix problems with {function}{/function} and {call} tags in different subtemplate cache files {forum topic 25452}
- bugfix Smarty_Security->allow_constants=false; did not disallow direct usage of defined constants like {SMARTY_DIR} {forum topic 25457}
- bugfix {block}{/block} tags did not work inside double quoted strings https://github.com/smarty-php/smarty/issues/18
15.03.2015
- bugfix $smarty->compile_check must be restored before rendering of a just updated cache file {forum 25452}
14.03.2015
- bugfix {nocache} {/nocache} tags corrupted code when used within a nocache section caused by a nocache template variable.
- bugfix template functions defined with {function} in an included subtemplate could not be called in nocache
mode with {call... nocache} if the subtemplate had it's own cache file {forum 25452}
10.03.2015
- bugfix {include ... nocache} whith variable file or compile_id attribute was not executed in nocache mode.
12.02.2015
- bugfix multiple Smarty::fetch() of same template when $smarty->merge_compiled_includes = true; could cause function already defined error
11.02.2015
- bugfix recursive {includes} did create E_NOTICE message when $smarty->merge_compiled_includes = true; (github issue #16)
22.01.2015
- new feature security can now control access to static methods and properties
see also NEW_FEATURES.txt
21.01.2015
- bugfix clearCompiledTemplates(), clearAll() and clear() could try to delete whole drive at wrong path permissions because realpath() fail (forum 25397)
- bugfix 'self::' and 'parent::' was interpreted in template syntax as static class
04.01.2015
- push last weeks changes to github
- different optimizations
- improvement automatically create different versions of compiled templates and config files depending
on property settings.
- optimization restructure template processing by moving code into classes it better belongs to
- optimization restructure config file processing
31.12.2014
- bugfix use function_exists('mb_get_info') for setting Smarty::$_MBSTRING.
Function mb_split could be overloaded depending on php.ini mbstring.func_overload
29.12.2014
- new feature security can now limit the template nesting level by property $max_template_nesting
see also NEW_FEATURES.txt (forum 25370)
29.12.2014
- new feature security can now disable special $smarty variables listed in property $disabled_special_smarty_vars
see also NEW_FEATURES.txt (forum 25370)
27.12.2014
- bugfix clear internal _is_file_cache when plugins_dir was modified
13.12.2014
- improvement optimization of lexer and parser resulting in a up to 30% higher compiling speed
11.12.2014
- bugfix resolve parser ambiguity between constant print tag {CONST} and other smarty tags after change of 09.12.2014
09.12.2014
- bugfix variables $null, $true and $false did not work after the change of 12.11.2014 (forum 25342)
- bugfix call of template function by a variable name did not work after latest changes (forum 25342)
23.11.2014
- bugfix a plugin with attached modifier could fail if the tag was immediately followed by another Smarty tag (since 3.1.21) (forum 25326)
13.11.2014
- improvement move autoload code into Autoloader.php. Use Composer autoloader when possible
12.11.2014
- new feature added support of namespaces to template code
08.11.2014 - 10.11.2014
- bugfix subtemplate called in nocache mode could be called with wrong compile_id when it did change on one of the calling templates
- improvement add code of template functions called in nocache mode dynamically to cache file (related to bugfix of 01.11.2014)
- bugfix Debug Console did not include all data from merged compiled subtemplates
04.11.2014
- new feature $smarty->debugging = true; => overwrite existing Debug Console window (old behaviour)
$smarty->debugging = 2; => individual Debug Console window by template name
03.11.2014
- bugfix Debug Console did not show included subtemplates since 3.1.17 (forum 25301)
- bugfix Modifier debug_print_var did not limit recursion or prevent recursive object display at Debug Console
(ATTENTION: parameter order has changed to be able to specify maximum recursion)
- bugfix Debug consol did not include subtemplate information with $smarty->merge_compiled_includes = true
- improvement The template variables are no longer displayed as objects on the Debug Console
- improvement $smarty->createData($parent = null, $name = null) new optional name parameter for display at Debug Console
- addition of some hooks for future extension of Debug Console
01.11.2014
- bugfix and enhancement on subtemplate {include} and template {function} tags.
* Calling a template which has a nocache section could fail if it was called from a cached and a not cached subtemplate.
* Calling the same subtemplate cached and not cached with the $smarty->merge_compiled_includes enabled could cause problems
* Many smaller related changes
30.10.2014
- bugfix access to class constant by object like {$object::CONST} or variable class name {$class::CONST} did not work (forum 25301)
26.10.2014
- bugfix E_NOTICE message was created during compilation when ASP tags '<%' or '%>' are in template source text
- bugfix merge_compiled_includes option failed when caching enables and same subtemplate was included cached and not cached
===== 3.1.21 ===== (18.10.2014)
18.10.2014
- composer moved to github
17.10.2014
- bugfix on $php_handling security and optimization of smarty_internal_parsetree (Thue Kristensen)
16.10.2014
- bugfix composer.json update
15.10.2014
- bugfix calling a new created cache file with fetch() and Smarty::CACHING_LIFETIME_SAVED multiple times did fail (forum 22350)
@@ -727,7 +1145,7 @@
15/07/2011
- bugfix individual cache_lifetime of {include} did not work correctly inside {block} tags
- added caches for Smarty_Template_Source and Smarty_Template_Compiled to reduce I/O for multiple cache_id rendering
- added caches for Smarty_Internal_TemplateSource and Smarty_Internal_TemplateCompiled to reduce I/O for multiple cache_id rendering
14/07/2011
- made Smarty::loadPlugin() respect the include_path if required
+2 -2
View File
@@ -21,7 +21,7 @@
],
"support": {
"irc": "irc://irc.freenode.org/smarty",
"issues": "http://code.google.com/p/smarty-php/issues/list",
"issues": "https://github.com/smarty-php/smarty/issues",
"forum": "http://www.smarty.net/forums/"
},
"require": {
@@ -31,7 +31,7 @@
"classmap": [
"libs/Smarty.class.php",
"libs/SmartyBC.class.php",
"libs/sysplugins/smarty_security.php"
"libs/sysplugins/"
]
},
"extra": {
+322
View File
@@ -0,0 +1,322 @@
<?php
/**
* PDO Cache Handler
* Allows you to store Smarty Cache files into your db.
* Example table :
* CREATE TABLE `smarty_cache` (
* `id` char(40) NOT NULL COMMENT 'sha1 hash',
* `name` varchar(250) NOT NULL,
* `cache_id` varchar(250) DEFAULT NULL,
* `compile_id` varchar(250) DEFAULT NULL,
* `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
* `expire` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
* `content` mediumblob NOT NULL,
* PRIMARY KEY (`id`),
* KEY `name` (`name`),
* KEY `cache_id` (`cache_id`),
* KEY `compile_id` (`compile_id`),
* KEY `modified` (`modified`),
* KEY `expire` (`expire`)
* ) ENGINE=InnoDB
* Example usage :
* $cnx = new PDO("mysql:host=localhost;dbname=mydb", "username", "password");
* $smarty->setCachingType('pdo');
* $smarty->loadPlugin('Smarty_CacheResource_Pdo');
* $smarty->registerCacheResource('pdo', new Smarty_CacheResource_Pdo($cnx, 'smarty_cache'));
*
* @author Beno!t POLASZEK - 2014
*/
class Smarty_CacheResource_Pdo extends Smarty_CacheResource_Custom
{
protected $fetchStatements = Array('default' => 'SELECT %2$s
FROM %1$s
WHERE 1
AND id = :id
AND cache_id IS NULL
AND compile_id IS NULL',
'withCacheId' => 'SELECT %2$s
FROM %1$s
WHERE 1
AND id = :id
AND cache_id = :cache_id
AND compile_id IS NULL',
'withCompileId' => 'SELECT %2$s
FROM %1$s
WHERE 1
AND id = :id
AND compile_id = :compile_id
AND cache_id IS NULL',
'withCacheIdAndCompileId' => 'SELECT %2$s
FROM %1$s
WHERE 1
AND id = :id
AND cache_id = :cache_id
AND compile_id = :compile_id');
protected $insertStatement = 'INSERT INTO %s
SET id = :id,
name = :name,
cache_id = :cache_id,
compile_id = :compile_id,
modified = CURRENT_TIMESTAMP,
expire = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL :expire SECOND),
content = :content
ON DUPLICATE KEY UPDATE
name = :name,
cache_id = :cache_id,
compile_id = :compile_id,
modified = CURRENT_TIMESTAMP,
expire = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL :expire SECOND),
content = :content';
protected $deleteStatement = 'DELETE FROM %1$s WHERE %2$s';
protected $truncateStatement = 'TRUNCATE TABLE %s';
protected $fetchColumns = 'modified, content';
protected $fetchTimestampColumns = 'modified';
protected $pdo, $table, $database;
/*
* Constructor
*
* @param PDO $pdo PDO : active connection
* @param string $table : table (or view) name
* @param string $database : optionnal - if table is located in another db
*/
public function __construct(PDO $pdo, $table, $database = null)
{
if (is_null($table)) {
throw new SmartyException("Table name for caching can't be null");
}
$this->pdo = $pdo;
$this->table = $table;
$this->database = $database;
$this->fillStatementsWithTableName();
}
/*
* Fills the table name into the statements.
*
* @return Current Instance
* @access protected
*/
protected function fillStatementsWithTableName()
{
foreach ($this->fetchStatements AS &$statement) {
$statement = sprintf($statement, $this->getTableName(), '%s');
}
$this->insertStatement = sprintf($this->insertStatement, $this->getTableName());
$this->deleteStatement = sprintf($this->deleteStatement, $this->getTableName(), '%s');
$this->truncateStatement = sprintf($this->truncateStatement, $this->getTableName());
return $this;
}
/*
* Gets the fetch statement, depending on what you specify
*
* @param string $columns : the column(s) name(s) you want to retrieve from the database
* @param string $id unique cache content identifier
* @param string|null $cache_id cache id
* @param string|null $compile_id compile id
* @access protected
*/
protected function getFetchStatement($columns, $id, $cache_id = null, $compile_id = null)
{
if (!is_null($cache_id) && !is_null($compile_id)) {
$query = $this->fetchStatements['withCacheIdAndCompileId'] AND $args = Array('id' => $id, 'cache_id' => $cache_id, 'compile_id' => $compile_id);
} elseif (is_null($cache_id) && !is_null($compile_id)) {
$query = $this->fetchStatements['withCompileId'] AND $args = Array('id' => $id, 'compile_id' => $compile_id);
} elseif (!is_null($cache_id) && is_null($compile_id)) {
$query = $this->fetchStatements['withCacheId'] AND $args = Array('id' => $id, 'cache_id' => $cache_id);
} else {
$query = $this->fetchStatements['default'] AND $args = Array('id' => $id);
}
$query = sprintf($query, $columns);
$stmt = $this->pdo->prepare($query);
foreach ($args AS $key => $value) {
$stmt->bindValue($key, $value);
}
return $stmt;
}
/**
* fetch cached content and its modification time from data source
*
* @param string $id unique cache content identifier
* @param string $name template name
* @param string|null $cache_id cache id
* @param string|null $compile_id compile id
* @param string $content cached content
* @param integer $mtime cache modification timestamp (epoch)
*
* @return void
* @access protected
*/
protected function fetch($id, $name, $cache_id = null, $compile_id = null, &$content, &$mtime)
{
$stmt = $this->getFetchStatement($this->fetchColumns, $id, $cache_id, $compile_id);
$stmt ->execute();
$row = $stmt->fetch();
$stmt ->closeCursor();
if ($row) {
$content = $this->outputContent($row['content']);
$mtime = strtotime($row['modified']);
} else {
$content = null;
$mtime = null;
}
}
/**
* Fetch cached content's modification timestamp from data source
* {@internal implementing this method is optional.
* Only implement it if modification times can be accessed faster than loading the complete cached content.}}
*
* @param string $id unique cache content identifier
* @param string $name template name
* @param string|null $cache_id cache id
* @param string|null $compile_id compile id
*
* @return integer|boolean timestamp (epoch) the template was modified, or false if not found
* @access protected
*/
// protected function fetchTimestamp($id, $name, $cache_id = null, $compile_id = null) {
// $stmt = $this->getFetchStatement($this->fetchTimestampColumns, $id, $cache_id, $compile_id);
// $stmt -> execute();
// $mtime = strtotime($stmt->fetchColumn());
// $stmt -> closeCursor();
// return $mtime;
// }
/**
* Save content to cache
*
* @param string $id unique cache content identifier
* @param string $name template name
* @param string|null $cache_id cache id
* @param string|null $compile_id compile id
* @param integer|null $exp_time seconds till expiration time in seconds or null
* @param string $content content to cache
*
* @return boolean success
* @access protected
*/
protected function save($id, $name, $cache_id = null, $compile_id = null, $exp_time, $content)
{
$stmt = $this->pdo->prepare($this->insertStatement);
$stmt ->bindValue('id', $id);
$stmt ->bindValue('name', $name);
$stmt ->bindValue('cache_id', $cache_id, (is_null($cache_id)) ? PDO::PARAM_NULL : PDO::PARAM_STR);
$stmt ->bindValue('compile_id', $compile_id, (is_null($compile_id)) ? PDO::PARAM_NULL : PDO::PARAM_STR);
$stmt ->bindValue('expire', (int) $exp_time, PDO::PARAM_INT);
$stmt ->bindValue('content', $this->inputContent($content));
$stmt ->execute();
return !!$stmt->rowCount();
}
/*
* Encodes the content before saving to database
*
* @param string $content
* @return string $content
* @access protected
*/
protected function inputContent($content)
{
return $content;
}
/*
* Decodes the content before saving to database
*
* @param string $content
* @return string $content
* @access protected
*/
protected function outputContent($content)
{
return $content;
}
/**
* Delete content from cache
*
* @param string|null $name template name
* @param string|null $cache_id cache id
* @param string|null $compile_id compile id
* @param integer|null|-1 $exp_time seconds till expiration or null
*
* @return integer number of deleted caches
* @access protected
*/
protected function delete($name = null, $cache_id = null, $compile_id = null, $exp_time = null)
{
// delete the whole cache
if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
// returning the number of deleted caches would require a second query to count them
$this->pdo->query($this->truncateStatement);
return - 1;
}
// build the filter
$where = array();
// equal test name
if ($name !== null) {
$where[] = 'name = ' . $this->pdo->quote($name);
}
// equal test cache_id and match sub-groups
if ($cache_id !== null) {
$where[] = '(cache_id = ' . $this->pdo->quote($cache_id)
. ' OR cache_id LIKE ' . $this->pdo->quote($cache_id . '|%') . ')';
}
// equal test compile_id
if ($compile_id !== null) {
$where[] = 'compile_id = ' . $this->pdo->quote($compile_id);
}
// for clearing expired caches
if ($exp_time === Smarty::CLEAR_EXPIRED) {
$where[] = 'expire < CURRENT_TIMESTAMP';
} // range test expiration time
elseif ($exp_time !== null) {
$where[] = 'modified < DATE_SUB(NOW(), INTERVAL ' . intval($exp_time) . ' SECOND)';
}
// run delete query
$query = $this->pdo->query(sprintf($this->deleteStatement, join(' AND ', $where)));
return $query->rowCount();
}
/**
* Gets the formatted table name
*
* @return string
* @access protected
*/
protected function getTableName()
{
return (is_null($this->database)) ? "`{$this->table}`" : "`{$this->database}`.`{$this->table}`";
}
}
+43
View File
@@ -0,0 +1,43 @@
<?php
/**
* PDO Cache Handler with GZIP support
* Example usage :
* $cnx = new PDO("mysql:host=localhost;dbname=mydb", "username", "password");
* $smarty->setCachingType('pdo_gzip');
* $smarty->loadPlugin('Smarty_CacheResource_Pdo_Gzip');
* $smarty->registerCacheResource('pdo_gzip', new Smarty_CacheResource_Pdo_Gzip($cnx, 'smarty_cache'));
*
* @require Smarty_CacheResource_Pdo class
* @author Beno!t POLASZEK - 2014
*/
require_once 'cacheresource.pdo.php';
class Smarty_CacheResource_Pdo_Gzip extends Smarty_CacheResource_Pdo
{
/*
* Encodes the content before saving to database
*
* @param string $content
* @return string $content
* @access protected
*/
protected function inputContent($content)
{
return gzdeflate($content);
}
/*
* Decodes the content before saving to database
*
* @param string $content
* @return string $content
* @access protected
*/
protected function outputContent($content)
{
return gzinflate($content);
}
}
+4 -8
View File
@@ -23,9 +23,9 @@ class Smarty_Resource_Extendsall extends Smarty_Internal_Resource_Extends
$uid = '';
$sources = array();
$exists = true;
foreach ($_template->smarty->getTemplateDir() as $key => $directory) {
foreach ($source->smarty->getTemplateDir() as $key => $directory) {
try {
$s = Smarty_Resource::source(null, $source->smarty, '[' . $key . ']' . $source->name);
$s = Smarty_Template_Source::load(null, $source->smarty, 'file:[' . $key . ']' . $source->name);
if (!$s->exists) {
continue;
}
@@ -38,9 +38,7 @@ class Smarty_Resource_Extendsall extends Smarty_Internal_Resource_Extends
if (!$sources) {
$source->exists = false;
$source->template = $_template;
return;
return;
}
$sources = array_reverse($sources, true);
@@ -52,9 +50,7 @@ class Smarty_Resource_Extendsall extends Smarty_Internal_Resource_Extends
$source->uid = sha1($uid);
$source->exists = $exists;
if ($_template && $_template->smarty->compile_check) {
$source->timestamp = $s->timestamp;
$source->timestamp = $s->getTimeStamp();
}
// need the template at getContent()
$source->template = $_template;
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
<HTML>
<HEAD>
<TITLE>{$title} - {$Name}</TITLE>
<TITLE>{$title} - {$Name}</TITLE>
</HEAD>
<BODY bgcolor="#ffffff">
+318
View File
@@ -0,0 +1,318 @@
<?php
/**
* Smarty Internal Plugin Configfilelexer
*
* This is the lexer to break the config file source into tokens
* @package Smarty
* @subpackage Config
* @author Uwe Tews
*/
/**
* Smarty_Internal_Configfilelexer
*
* This is the config file lexer.
* It is generated from the smarty_internal_configfilelexer.plex file
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
class Smarty_Internal_Configfilelexer
{
/**
* Source
*
* @var string
*/
public $data;
/**
* byte counter
*
* @var int
*/
public $counter;
/**
* token number
*
* @var int
*/
public $token;
/**
* token value
*
* @var string
*/
public $value;
/**
* current line
*
* @var int
*/
public $line;
/**
* state number
*
* @var int
*/
public $state = 1;
/**
* Smarty object
*
* @var Smarty
*/
public $smarty = null;
/**
* compiler object
*
* @var Smarty_Internal_Config_File_Compiler
*/
private $compiler = null;
/**
* copy of config_booleanize
*
* @var bool
*/
private $configBooleanize = false;
/**
* trace file
*
* @var resource
*/
public $yyTraceFILE;
/**
* trace prompt
*
* @var string
*/
public $yyTracePrompt;
/**
* state names
*
* @var array
*/
public $state_name = array(1 => 'START', 2 => 'VALUE', 3 => 'NAKED_STRING_VALUE', 4 => 'COMMENT', 5 => 'SECTION', 6 => 'TRIPPLE');
/**
* storage for assembled token patterns
*
* @var string
*/
private $yy_global_pattern1 = null;
private $yy_global_pattern2 = null;
private $yy_global_pattern3 = null;
private $yy_global_pattern4 = null;
private $yy_global_pattern5 = null;
private $yy_global_pattern6 = null;
/**
* token names
*
* @var array
*/
public $smarty_token_names = array( // Text for parser error messages
);
/**
* constructor
*
* @param string $data template source
* @param Smarty_Internal_Config_File_Compiler $compiler
*/
function __construct($data, Smarty_Internal_Config_File_Compiler $compiler)
{
// set instance object
self::instance($this);
$this->data = $data . "\n"; //now all lines are \n-terminated
$this->counter = 0;
if (preg_match('/^\xEF\xBB\xBF/', $this->data, $match)) {
$this->counter += strlen($match[0]);
}
$this->line = 1;
$this->compiler = $compiler;
$this->smarty = $compiler->smarty;
$this->configBooleanize = $this->smarty->config_booleanize;
}
public static function &instance($new_instance = null)
{
static $instance = null;
if (isset($new_instance) && is_object($new_instance)) {
$instance = $new_instance;
}
return $instance;
}
public function PrintTrace()
{
$this->yyTraceFILE = fopen('php://output', 'w');
$this->yyTracePrompt = '<br>';
}
/*!lex2php
%input $this->data
%counter $this->counter
%token $this->token
%value $this->value
%line $this->line
commentstart = /#|;/
openB = /\[/
closeB = /\]/
section = /.*?(?=[\.=\[\]\r\n])/
equal = /=/
whitespace = /[ \t\r]+/
dot = /\./
id = /[0-9]*[a-zA-Z_]\w*/
newline = /\n/
single_quoted_string = /'[^'\\]*(?:\\.[^'\\]*)*'(?=[ \t\r]*[\n#;])/
double_quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"(?=[ \t\r]*[\n#;])/
tripple_quotes = /"""/
tripple_quotes_end = /"""(?=[ \t\r]*[\n#;])/
text = /[\S\s]/
float = /\d+\.\d+(?=[ \t\r]*[\n#;])/
int = /\d+(?=[ \t\r]*[\n#;])/
maybe_bool = /[a-zA-Z]+(?=[ \t\r]*[\n#;])/
naked_string = /[^\n]+?(?=[ \t\r]*\n)/
*/
/*!lex2php
%statename START
commentstart {
$this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
$this->yypushstate(self::COMMENT);
}
openB {
$this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
$this->yypushstate(self::SECTION);
}
closeB {
$this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
}
equal {
$this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
$this->yypushstate(self::VALUE);
}
whitespace {
return false;
}
newline {
$this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
}
id {
$this->token = Smarty_Internal_Configfileparser::TPC_ID;
}
text {
$this->token = Smarty_Internal_Configfileparser::TPC_OTHER;
}
*/
/*!lex2php
%statename VALUE
whitespace {
return false;
}
float {
$this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
$this->yypopstate();
}
int {
$this->token = Smarty_Internal_Configfileparser::TPC_INT;
$this->yypopstate();
}
tripple_quotes {
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
$this->yypushstate(self::TRIPPLE);
}
single_quoted_string {
$this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
$this->yypopstate();
}
double_quoted_string {
$this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
$this->yypopstate();
}
maybe_bool {
if (!$this->configBooleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes", "no")) ) {
$this->yypopstate();
$this->yypushstate(self::NAKED_STRING_VALUE);
return true; //reprocess in new state
} else {
$this->token = Smarty_Internal_Configfileparser::TPC_BOOL;
$this->yypopstate();
}
}
naked_string {
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
$this->yypopstate();
}
newline {
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
$this->value = "";
$this->yypopstate();
}
*/
/*!lex2php
%statename NAKED_STRING_VALUE
naked_string {
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
$this->yypopstate();
}
*/
/*!lex2php
%statename COMMENT
whitespace {
return false;
}
naked_string {
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
}
newline {
$this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
$this->yypopstate();
}
*/
/*!lex2php
%statename SECTION
dot {
$this->token = Smarty_Internal_Configfileparser::TPC_DOT;
}
section {
$this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
$this->yypopstate();
}
*/
/*!lex2php
%statename TRIPPLE
tripple_quotes_end {
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
$this->yypopstate();
$this->yypushstate(self::START);
}
text {
$to = strlen($this->data);
preg_match("/\"\"\"[ \t\r]*[\n#;]/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
if (isset($match[0][1])) {
$to = $match[0][1];
} else {
$this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
}
$this->value = substr($this->data,$this->counter,$to-$this->counter);
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
}
*/
}
+362
View File
@@ -0,0 +1,362 @@
/**
* Smarty Internal Plugin Configfileparser
*
* This is the config file parser
*
*
* @package Smarty
* @subpackage Config
* @author Uwe Tews
*/
%name TPC_
%declare_class {
/**
* Smarty Internal Plugin Configfileparse
*
* This is the config file parser.
* It is generated from the smarty_internal_configfileparser.y file
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
class Smarty_Internal_Configfileparser
}
%include_class
{
/**
* result status
*
* @var bool
*/
public $successful = true;
/**
* return value
*
* @var mixed
*/
public $retvalue = 0;
/**
* @var
*/
public $yymajor;
/**
* lexer object
*
* @var Smarty_Internal_Configfilelexer
*/
private $lex;
/**
* internal error flag
*
* @var bool
*/
private $internalError = false;
/**
* compiler object
*
* @var Smarty_Internal_Config_File_Compiler
*/
public $compiler = null;
/**
* smarty object
*
* @var Smarty
*/
public $smarty = null;
/**
* copy of config_overwrite property
*
* @var bool
*/
private $configOverwrite = false;
/**
* copy of config_read_hidden property
*
* @var bool
*/
private $configReadHidden = false;
/**
* helper map
*
* @var array
*/
private static $escapes_single = Array('\\' => '\\',
'\'' => '\'');
/**
* constructor
*
* @param Smarty_Internal_Configfilelexer $lex
* @param Smarty_Internal_Config_File_Compiler $compiler
*/
function __construct(Smarty_Internal_Configfilelexer $lex, Smarty_Internal_Config_File_Compiler $compiler)
{
// set instance object
self::instance($this);
$this->lex = $lex;
$this->smarty = $compiler->smarty;
$this->compiler = $compiler;
$this->configOverwrite = $this->smarty->config_overwrite;
$this->configReadHidden = $this->smarty->config_read_hidden;
}
/**
* @param null $new_instance
*
* @return null
*/
public static function &instance($new_instance = null)
{
static $instance = null;
if (isset($new_instance) && is_object($new_instance)) {
$instance = $new_instance;
}
return $instance;
}
/**
* parse optional boolean keywords
*
* @param string $str
*
* @return bool
*/
private function parse_bool($str)
{
$str = strtolower($str);
if (in_array($str, array('on', 'yes', 'true'))) {
$res = true;
} else {
$res = false;
}
return $res;
}
/**
* parse single quoted string
* remove outer quotes
* unescape inner quotes
*
* @param string $qstr
*
* @return string
*/
private static function parse_single_quoted_string($qstr)
{
$escaped_string = substr($qstr, 1, strlen($qstr) - 2); //remove outer quotes
$ss = preg_split('/(\\\\.)/', $escaped_string, - 1, PREG_SPLIT_DELIM_CAPTURE);
$str = "";
foreach ($ss as $s) {
if (strlen($s) === 2 && $s[0] === '\\') {
if (isset(self::$escapes_single[$s[1]])) {
$s = self::$escapes_single[$s[1]];
}
}
$str .= $s;
}
return $str;
}
/**
* parse double quoted string
*
* @param string $qstr
*
* @return string
*/
private static function parse_double_quoted_string($qstr)
{
$inner_str = substr($qstr, 1, strlen($qstr) - 2);
return stripcslashes($inner_str);
}
/**
* parse triple quoted string
*
* @param string $qstr
*
* @return string
*/
private static function parse_tripple_double_quoted_string($qstr)
{
return stripcslashes($qstr);
}
/**
* set a config variable in target array
*
* @param array $var
* @param array $target_array
*/
private function set_var(Array $var, Array &$target_array)
{
$key = $var["key"];
$value = $var["value"];
if ($this->configOverwrite || !isset($target_array['vars'][$key])) {
$target_array['vars'][$key] = $value;
} else {
settype($target_array['vars'][$key], 'array');
$target_array['vars'][$key][] = $value;
}
}
/**
* add config variable to global vars
*
* @param array $vars
*/
private function add_global_vars(Array $vars)
{
if (!isset($this->compiler->config_data['vars'])) {
$this->compiler->config_data['vars'] = Array();
}
foreach ($vars as $var) {
$this->set_var($var, $this->compiler->config_data);
}
}
/**
* add config variable to section
*
* @param string $section_name
* @param array $vars
*/
private function add_section_vars($section_name, Array $vars)
{
if (!isset($this->compiler->config_data['sections'][$section_name]['vars'])) {
$this->compiler->config_data['sections'][$section_name]['vars'] = Array();
}
foreach ($vars as $var) {
$this->set_var($var, $this->compiler->config_data['sections'][$section_name]);
}
}
}
%token_prefix TPC_
%parse_accept
{
$this->successful = !$this->internalError;
$this->internalError = false;
$this->retvalue = $this->_retvalue;
}
%syntax_error
{
$this->internalError = true;
$this->yymajor = $yymajor;
$this->compiler->trigger_config_file_error();
}
%stack_overflow
{
$this->internalError = true;
$this->compiler->trigger_config_file_error("Stack overflow in configfile parser");
}
// Complete config file
start(res) ::= global_vars sections. {
res = null;
}
// Global vars
global_vars(res) ::= var_list(vl). {
$this->add_global_vars(vl);
res = null;
}
// Sections
sections(res) ::= sections section. {
res = null;
}
sections(res) ::= . {
res = null;
}
section(res) ::= OPENB SECTION(i) CLOSEB newline var_list(vars). {
$this->add_section_vars(i, vars);
res = null;
}
section(res) ::= OPENB DOT SECTION(i) CLOSEB newline var_list(vars). {
if ($this->configReadHidden) {
$this->add_section_vars(i, vars);
}
res = null;
}
// Var list
var_list(res) ::= var_list(vl) newline. {
res = vl;
}
var_list(res) ::= var_list(vl) var(v). {
res = array_merge(vl, Array(v));
}
var_list(res) ::= . {
res = Array();
}
// Var
var(res) ::= ID(id) EQUAL value(v). {
res = Array("key" => id, "value" => v);
}
value(res) ::= FLOAT(i). {
res = (float) i;
}
value(res) ::= INT(i). {
res = (int) i;
}
value(res) ::= BOOL(i). {
res = $this->parse_bool(i);
}
value(res) ::= SINGLE_QUOTED_STRING(i). {
res = self::parse_single_quoted_string(i);
}
value(res) ::= DOUBLE_QUOTED_STRING(i). {
res = self::parse_double_quoted_string(i);
}
value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_TEXT(c) TRIPPLE_QUOTES_END(ii). {
res = self::parse_tripple_double_quoted_string(c);
}
value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_QUOTES_END(ii). {
res = '';
}
value(res) ::= NAKED_STRING(i). {
res = i;
}
// NOTE: this is not a valid rule
// It is added hier to produce a usefull error message on a missing '=';
value(res) ::= OTHER(i). {
res = i;
}
// Newline and comments
newline(res) ::= NEWLINE. {
res = null;
}
newline(res) ::= COMMENTSTART NEWLINE. {
res = null;
}
newline(res) ::= COMMENTSTART NAKED_STRING NEWLINE. {
res = null;
}
+672
View File
@@ -0,0 +1,672 @@
<?php
/*
* This file is part of Smarty.
*
* (c) 2015 Uwe Tews
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Smarty_Internal_Templatelexer
* This is the template file lexer.
* It is generated from the smarty_internal_templatelexer.plex file
*
*
* @author Uwe Tews <uwe.tews@googlemail.com>
*/
class Smarty_Internal_Templatelexer
{
/**
* Source
*
* @var string
*/
public $data;
/**
* byte counter
*
* @var int
*/
public $counter;
/**
* token number
*
* @var int
*/
public $token;
/**
* token value
*
* @var string
*/
public $value;
/**
* current line
*
* @var int
*/
public $line;
/**
* tag start line
*
* @var
*/
public $taglineno;
/**
* php code type
*
* @var string
*/
public $phpType = '';
/**
* escaped left delimiter
*
* @var string
*/
public $ldel = '';
/**
* escaped left delimiter length
*
* @var int
*/
public $ldel_length = 0;
/**
* escaped right delimiter
*
* @var string
*/
public $rdel = '';
/**
* escaped right delimiter length
*
* @var int
*/
public $rdel_length = 0;
/**
* state number
*
* @var int
*/
public $state = 1;
/**
* Smarty object
*
* @var Smarty
*/
public $smarty = null;
/**
* compiler object
*
* @var Smarty_Internal_TemplateCompilerBase
*/
public $compiler = null;
/**
* literal tag nesting level
*
* @var int
*/
private $literal_cnt = 0;
/**
* PHP start tag string
*
* @var string
*/
/**
* trace file
*
* @var resource
*/
public $yyTraceFILE;
/**
* trace prompt
*
* @var string
*/
public $yyTracePrompt;
/**
* XML flag true while processing xml
*
* @var bool
*/
public $is_xml = false;
/**
* state names
*
* @var array
*/
public $state_name = array(1 => 'TEXT', 2 => 'TAG', 3 => 'TAGBODY', 4 => 'LITERAL', 5 => 'DOUBLEQUOTEDSTRING',);
/**
* storage for assembled token patterns
*
* @var string
*/
private $yy_global_pattern1 = null;
private $yy_global_pattern2 = null;
private $yy_global_pattern3 = null;
private $yy_global_pattern4 = null;
private $yy_global_pattern5 = null;
/**
* token names
*
* @var array
*/
public $smarty_token_names = array( // Text for parser error messages
'NOT' => '(!,not)',
'OPENP' => '(',
'CLOSEP' => ')',
'OPENB' => '[',
'CLOSEB' => ']',
'PTR' => '->',
'APTR' => '=>',
'EQUAL' => '=',
'NUMBER' => 'number',
'UNIMATH' => '+" , "-',
'MATH' => '*" , "/" , "%',
'INCDEC' => '++" , "--',
'SPACE' => ' ',
'DOLLAR' => '$',
'SEMICOLON' => ';',
'COLON' => ':',
'DOUBLECOLON' => '::',
'AT' => '@',
'HATCH' => '#',
'QUOTE' => '"',
'BACKTICK' => '`',
'VERT' => '"|" modifier',
'DOT' => '.',
'COMMA' => '","',
'QMARK' => '"?"',
'ID' => 'id, name',
'TEXT' => 'text',
'LDELSLASH' => '{/..} closing tag',
'LDEL' => '{...} Smarty tag',
'COMMENT' => 'comment',
'AS' => 'as',
'TO' => 'to',
'PHP' => '"<?php", "<%", "{php}" tag',
'LOGOP' => '"<", "==" ... logical operator',
'TLOGOP' => '"lt", "eq" ... logical operator; "is div by" ... if condition',
'SCOND' => '"is even" ... if condition',
);
/**
* constructor
*
* @param string $data template source
* @param Smarty_Internal_TemplateCompilerBase $compiler
*/
function __construct($data, Smarty_Internal_TemplateCompilerBase $compiler)
{
$this->data = $data;
$this->counter = 0;
if (preg_match('~^\xEF\xBB\xBF~i', $this->data, $match)) {
$this->counter += strlen($match[0]);
}
$this->line = 1;
$this->smarty = $compiler->smarty;
$this->compiler = $compiler;
$this->ldel = preg_quote($this->smarty->left_delimiter, '~');
$this->ldel_length = strlen($this->smarty->left_delimiter);
$this->rdel = preg_quote($this->smarty->right_delimiter, '~');
$this->rdel_length = strlen($this->smarty->right_delimiter);
$this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter;
$this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter;
}
public function PrintTrace()
{
$this->yyTraceFILE = fopen('php://output', 'w');
$this->yyTracePrompt = '<br>';
}
/*
* Check if this tag is autoliteral
*/
public function isAutoLiteral ()
{
return $this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false;
}
/*!lex2php
%input $this->data
%counter $this->counter
%token $this->token
%value $this->value
%line $this->line
linebreak = ~[\t ]*[\r\n]+[\t ]*~
text = ~[\S\s]~
textdoublequoted = ~([^"\\]*?)((?:\\.[^"\\]*?)*?)(?=(SMARTYldel|\$|`\$|"))~
namespace = ~([0-9]*[a-zA-Z_]\w*)?(\\[0-9]*[a-zA-Z_]\w*)+~
all = ~[\S\s]+~
emptyjava = ~[{][}]~
phptag = ~(SMARTYldel\s*php(.*?)SMARTYrdel)|(SMARTYldel\s*[/]phpSMARTYrdel)~
phpstart = ~(<[?]((php\s+|=)|\s+))|(<[%])|(<[?]xml\s+)|(<script\s+language\s*=\s*["']?\s*php\s*["']?\s*>)|([?][>])|([%][>])~
slash = ~[/]~
ldel = ~SMARTYldel\s*~
rdel = ~\s*SMARTYrdel~
nocacherdel = ~(\s+nocache)?\s*SMARTYrdel~
notblockid = ~(?:(?!block)[0-9]*[a-zA-Z_]\w*)~
smartyblockchildparent = ~[\$]smarty\.block\.(child|parent)~
integer = ~\d+~
hex = ~0[xX][0-9a-fA-F]+~
math = ~\s*([*]{1,2}|[%/^&]|[<>]{2})\s*~
comment = ~SMARTYldel[*]~
incdec = ~([+]|[-]){2}~
unimath = ~\s*([+]|[-])\s*~
openP = ~\s*[(]\s*~
closeP = ~\s*[)]~
openB = ~\[\s*~
closeB = ~\s*\]~
dollar = ~[$]~
dot = ~[.]~
comma = ~\s*[,]\s*~
doublecolon = ~[:]{2}~
colon = ~\s*[:]\s*~
at = ~[@]~
hatch = ~[#]~
semicolon = ~\s*[;]\s*~
equal = ~\s*[=]\s*~
space = ~\s+~
ptr = ~\s*[-][>]\s*~
aptr = ~\s*[=][>]\s*~
singlequotestring = ~'[^'\\]*(?:\\.[^'\\]*)*'~
backtick = ~[`]~
vert = ~[|]~
qmark = ~\s*[?]\s*~
constant = ~([_]+[A-Z0-9][0-9A-Z_]*|[A-Z][0-9A-Z_]*)(?![0-9A-Z_]*[a-z])~
attr = ~\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\s*[=]\s*~
id = ~[0-9]*[a-zA-Z_]\w*~
literal = ~literal~
strip = ~strip~
lop = ~\s*(([!=][=]{1,2})|([<][=>]?)|([>][=]?)|[&|]{2})\s*~
tlop = ~\s+(eq|ne|neq|gt|ge|gte|lt|le|lte|mod|and|or|xor|(is\s+(not\s+)?(odd|even|div)\s+by))\s+~
scond = ~\s+is\s+(not\s+)?(odd|even)~
isin = ~\s+is\s+in\s+~
as = ~\s+as\s+~
to = ~\s+to\s+~
step = ~\s+step\s+~
block = ~block~
if = ~(if|elseif|else if|while)\s+~
for = ~for\s+~
foreach = ~foreach(?![^\s])~
setfilter = ~setfilter\s+~
instanceof = ~\s+instanceof\s+~
not = ~([!]\s*)|(not\s+)~
typecast = ~[(](int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)[)]\s*~
double_quote = ~["]~
single_quote = ~[']~
*/
/*!lex2php
%statename TEXT
emptyjava {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
comment {
preg_match("~[*]{$this->rdel}~",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
if (isset($match[0][1])) {
$to = $match[0][1] + strlen($match[0][0]);
} else {
$this->compiler->trigger_template_error ("missing or misspelled comment closing tag '*{$this->smarty->right_delimiter}'");
}
$this->value = substr($this->data,$this->counter,$to-$this->counter);
return false;
}
phptag {
$obj = new Smarty_Internal_Compile_Private_Php();
$obj->parsePhp($this);
}
ldel literal rdel {
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
} else {
$this->token = Smarty_Internal_Templateparser::TP_LITERALSTART;
$this->yypushstate(self::LITERAL);
}
}
ldel {
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
} else {
$this->yypushstate(self::TAG);
return true;
}
}
rdel {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
phpstart {
$obj = new Smarty_Internal_Compile_Private_Php();
$obj->parsePhp($this);
}
text {
$to = strlen($this->data);
preg_match("~($this->ldel)|(<[?]((php\s+|=)|\s+))|(<[%])|(<[?]xml\s+)|(<script\s+language\s*=\s*[\"']?\s*php\s*[\"']?\s*>)|([?][>])|([%][>])~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
if (isset($match[0][1])) {
$to = $match[0][1];
}
$this->value = substr($this->data,$this->counter,$to-$this->counter);
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
*/
/*!lex2php
%statename TAG
ldel if {
$this->token = Smarty_Internal_Templateparser::TP_LDELIF;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel for {
$this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel foreach {
$this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel setfilter {
$this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel id nocacherdel {
$this->yypopstate();
$this->token = Smarty_Internal_Templateparser::TP_SIMPLETAG;
$this->taglineno = $this->line;
}
ldel slash notblockid rdel {
$this->yypopstate();
$this->token = Smarty_Internal_Templateparser::TP_CLOSETAG;
$this->taglineno = $this->line;
}
ldel dollar id nocacherdel {
if ($this->_yy_stack[count($this->_yy_stack)-1] == self::TEXT) {
$this->yypopstate();
$this->token = Smarty_Internal_Templateparser::TP_SIMPELOUTPUT;
$this->taglineno = $this->line;
} else {
$this->value = $this->smarty->left_delimiter;
$this->token = Smarty_Internal_Templateparser::TP_LDEL;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
}
ldel slash {
$this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel {
$this->token = Smarty_Internal_Templateparser::TP_LDEL;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
*/
/*!lex2php
%statename TAGBODY
rdel {
$this->token = Smarty_Internal_Templateparser::TP_RDEL;
$this->yypopstate();
}
ldel {
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
} else {
$this->yypushstate(self::TAG);
return true;
}
}
double_quote {
$this->token = Smarty_Internal_Templateparser::TP_QUOTE;
$this->yypushstate(self::DOUBLEQUOTEDSTRING);
}
singlequotestring {
$this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING;
}
smartyblockchildparent {
$this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILDPARENT;
$this->taglineno = $this->line;
}
dollar id {
$this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
}
dollar {
$this->token = Smarty_Internal_Templateparser::TP_DOLLAR;
}
isin {
$this->token = Smarty_Internal_Templateparser::TP_ISIN;
}
as {
$this->token = Smarty_Internal_Templateparser::TP_AS;
}
to {
$this->token = Smarty_Internal_Templateparser::TP_TO;
}
step {
$this->token = Smarty_Internal_Templateparser::TP_STEP;
}
instanceof {
$this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF;
}
lop {
$this->token = Smarty_Internal_Templateparser::TP_LOGOP;
}
tlop {
$this->token = Smarty_Internal_Templateparser::TP_TLOGOP;
}
scond {
$this->token = Smarty_Internal_Templateparser::TP_SINGLECOND;
}
not{
$this->token = Smarty_Internal_Templateparser::TP_NOT;
}
typecast {
$this->token = Smarty_Internal_Templateparser::TP_TYPECAST;
}
openP {
$this->token = Smarty_Internal_Templateparser::TP_OPENP;
}
closeP {
$this->token = Smarty_Internal_Templateparser::TP_CLOSEP;
}
openB {
$this->token = Smarty_Internal_Templateparser::TP_OPENB;
}
closeB {
$this->token = Smarty_Internal_Templateparser::TP_CLOSEB;
}
ptr {
$this->token = Smarty_Internal_Templateparser::TP_PTR;
}
aptr {
$this->token = Smarty_Internal_Templateparser::TP_APTR;
}
equal {
$this->token = Smarty_Internal_Templateparser::TP_EQUAL;
}
incdec {
$this->token = Smarty_Internal_Templateparser::TP_INCDEC;
}
unimath {
$this->token = Smarty_Internal_Templateparser::TP_UNIMATH;
}
math {
$this->token = Smarty_Internal_Templateparser::TP_MATH;
}
at {
$this->token = Smarty_Internal_Templateparser::TP_AT;
}
hatch {
$this->token = Smarty_Internal_Templateparser::TP_HATCH;
}
attr {
// resolve conflicts with shorttag and right_delimiter starting with '='
if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->rdel_length) == $this->smarty->right_delimiter) {
preg_match("~\s+~",$this->value,$match);
$this->value = $match[0];
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
} else {
$this->token = Smarty_Internal_Templateparser::TP_ATTR;
}
}
namespace {
$this->token = Smarty_Internal_Templateparser::TP_NAMESPACE;
}
id {
$this->token = Smarty_Internal_Templateparser::TP_ID;
}
integer {
$this->token = Smarty_Internal_Templateparser::TP_INTEGER;
}
backtick {
$this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
$this->yypopstate();
}
vert {
$this->token = Smarty_Internal_Templateparser::TP_VERT;
}
dot {
$this->token = Smarty_Internal_Templateparser::TP_DOT;
}
comma {
$this->token = Smarty_Internal_Templateparser::TP_COMMA;
}
semicolon {
$this->token = Smarty_Internal_Templateparser::TP_SEMICOLON;
}
doublecolon {
$this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON;
}
colon {
$this->token = Smarty_Internal_Templateparser::TP_COLON;
}
qmark {
$this->token = Smarty_Internal_Templateparser::TP_QMARK;
}
hex {
$this->token = Smarty_Internal_Templateparser::TP_HEX;
}
space {
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
}
text {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
*/
/*!lex2php
%statename LITERAL
ldel literal rdel {
$this->literal_cnt++;
$this->token = Smarty_Internal_Templateparser::TP_LITERAL;
}
ldel slash literal rdel {
if ($this->literal_cnt) {
$this->literal_cnt--;
$this->token = Smarty_Internal_Templateparser::TP_LITERAL;
} else {
$this->token = Smarty_Internal_Templateparser::TP_LITERALEND;
$this->yypopstate();
}
}
text {
$to = strlen($this->data);
preg_match("~{$this->ldel}[/]?literal{$this->rdel}~i",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
if (isset($match[0][1])) {
$to = $match[0][1];
} else {
$this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
}
$this->value = substr($this->data,$this->counter,$to-$this->counter);
$this->token = Smarty_Internal_Templateparser::TP_LITERAL;
}
*/
/*!lex2php
%statename DOUBLEQUOTEDSTRING
ldel literal rdel {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
ldel slash literal rdel {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
ldel slash {
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
} else {
$this->yypushstate(self::TAG);
return true;
}
}
ldel id {
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
} else {
$this->yypushstate(self::TAG);
return true;
}
}
ldel {
if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
} else {
$this->token = Smarty_Internal_Templateparser::TP_LDEL;
$this->taglineno = $this->line;
$this->yypushstate(self::TAGBODY);
}
}
double_quote {
$this->token = Smarty_Internal_Templateparser::TP_QUOTE;
$this->yypopstate();
}
backtick dollar {
$this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
$this->value = substr($this->value,0,-1);
$this->yypushstate(self::TAGBODY);
$this->taglineno = $this->line;
}
dollar id {
$this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
}
dollar {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
textdoublequoted {
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
text {
$to = strlen($this->data);
$this->value = substr($this->data,$this->counter,$to-$this->counter);
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
*/
}
File diff suppressed because it is too large Load Diff
+124
View File
@@ -0,0 +1,124 @@
<?php
/**
* Smarty Autoloader
*
* @package Smarty
*/
/**
* Smarty Autoloader
*
* @package Smarty
* @author Uwe Tews
* Usage:
* require_once '...path/Autoloader.php';
* Smarty_Autoloader::register();
* $smarty = new Smarty();
* Note: This autoloader is not needed if you use Composer.
* Composer will automatically add the classes of the Smarty package to it common autoloader.
*/
class Smarty_Autoloader
{
/**
* Filepath to Smarty root
*
* @var string
*/
public static $SMARTY_DIR = '';
/**
* Filepath to Smarty internal plugins
*
* @var string
*/
public static $SMARTY_SYSPLUGINS_DIR = '';
/**
* Array with Smarty core classes and their filename
*
* @var array
*/
public static $rootClasses = array('smarty' => 'Smarty.class.php', 'smartybc' => 'SmartyBC.class.php',);
/**
* Registers Smarty_Autoloader backward compatible to older installations.
*
* @param bool $prepend Whether to prepend the autoloader or not.
*/
public static function registerBC($prepend = false)
{
/**
* register the class autoloader
*/
if (!defined('SMARTY_SPL_AUTOLOAD')) {
define('SMARTY_SPL_AUTOLOAD', 0);
}
if (SMARTY_SPL_AUTOLOAD &&
set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false
) {
$registeredAutoLoadFunctions = spl_autoload_functions();
if (!isset($registeredAutoLoadFunctions['spl_autoload'])) {
spl_autoload_register();
}
} else {
self::register($prepend);
}
}
/**
* Registers Smarty_Autoloader as an SPL autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not.
*/
public static function register($prepend = false)
{
self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : dirname(__FILE__) . DIRECTORY_SEPARATOR;
self::$SMARTY_SYSPLUGINS_DIR = defined('SMARTY_SYSPLUGINS_DIR') ? SMARTY_SYSPLUGINS_DIR :
self::$SMARTY_DIR . 'sysplugins' . DIRECTORY_SEPARATOR;
if (version_compare(phpversion(), '5.3.0', '>=')) {
spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
} else {
spl_autoload_register(array(__CLASS__, 'autoload'));
}
}
/**
* Handles auto loading of classes.
*
* @param string $class A class name.
*/
public static function autoload($class)
{
$_class = strtolower($class);
$file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php';
if (strpos($_class, 'smarty_internal_') === 0) {
if (strpos($_class, 'smarty_internal_compile_') === 0) {
if (is_file($file)) {
require $file;
}
return;
}
@include $file;
return;
}
if (preg_match('/^(smarty_(((template_(source|config|cache|compiled|resource_base))|((cached|compiled)?resource)|(variable|security)))|(smarty(bc)?)$)/',
$_class, $match)) {
if (!empty($match[3])) {
@include $file;
return;
} elseif (!empty($match[9]) && isset(self::$rootClasses[$_class])) {
$file = self::$rootClasses[$_class];
require $file;
return;
}
}
if (0 !== strpos($_class, 'smarty')) {
return;
}
if (is_file($file)) {
require $file;
return;
}
return;
}
}
+547 -752
View File
File diff suppressed because it is too large Load Diff
+11 -23
View File
@@ -44,6 +44,13 @@ class SmartyBC extends Smarty
*/
public $_version = self::SMARTY_VERSION;
/**
* This is an array of directories where trusted php scripts reside.
*
* @var array
*/
public $trusted_dir = array();
/**
* Initialize new SmartyBC object
*
@@ -52,8 +59,6 @@ class SmartyBC extends Smarty
public function __construct(array $options = array())
{
parent::__construct($options);
// register {php} tag
$this->registerPlugin('block', 'php', 'smarty_php_tag');
}
/**
@@ -115,10 +120,10 @@ class SmartyBC extends Smarty
/**
* Registers object to be used in templates
*
* @param string $object name of template object
* @param object $object_impl the referenced PHP object to register
* @param array $allowed list of allowed methods (empty = all)
* @param boolean $smarty_args smarty argument format, else traditional
* @param string $object name of template object
* @param object $object_impl the referenced PHP object to register
* @param array $allowed list of allowed methods (empty = all)
* @param boolean $smarty_args smarty argument format, else traditional
* @param array $block_methods list of methods that are block format
*
* @throws SmartyException
@@ -448,20 +453,3 @@ class SmartyBC extends Smarty
trigger_error("Smarty error: $error_msg", $error_type);
}
}
/**
* Smarty {php}{/php} block function
*
* @param array $params parameter list
* @param string $content contents of the block
* @param object $template template object
* @param boolean &$repeat repeat flag
*
* @return string content re-formatted
*/
function smarty_php_tag($params, $content, $template, &$repeat)
{
eval($content);
return '';
}
+40 -17
View File
@@ -5,7 +5,7 @@
<title>Smarty Debug Console</title>
<style type="text/css">
{literal}
body, h1, h2, td, th, p {
body, h1, h2, h3, td, th, p {
font-family: sans-serif;
font-weight: normal;
font-size: 0.9em;
@@ -31,6 +31,13 @@
padding: 2px;
border-top: 1px solid black;
}
h3 {
text-align: left;
font-weight: bold;
color: black;
font-size: 0.7em;
padding: 2px;
}
body {
background: black;
@@ -54,7 +61,6 @@
font-family: monospace;
vertical-align: top;
text-align: left;
width: 50%;
}
td {
@@ -74,8 +80,20 @@
font-style: italic;
}
#bold div {
color: black;
font-weight: bold;
}
#blue h3 {
color: blue;
}
#normal div {
color: black;
font-weight: normal;
}
#table_assigned_vars th {
color: blue;
font-weight: bold;
}
#table_config_vars th {
@@ -87,18 +105,17 @@
</head>
<body>
<h1>Smarty Debug Console
- {if isset($template_name)}{$template_name|debug_print_var nofilter}{else}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
<h1>Smarty {Smarty::SMARTY_VERSION} Debug Console
- {if isset($template_name)}{$template_name|debug_print_var nofilter} {/if}{if !empty($template_data)}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
{if !empty($template_data)}
<h2>included templates &amp; config files (load time in seconds)</h2>
<div>
{foreach $template_data as $template}
<font color=brown>{$template.name}</font>
<span class="exectime">
(compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"}
)
</span>
<br>&nbsp;&nbsp;<span class="exectime">
(compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"})
</span>
<br>
{/foreach}
</div>
@@ -109,19 +126,24 @@
<table id="table_assigned_vars">
{foreach $assigned_vars as $vars}
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
<th>${$vars@key|escape:'html'}</th>
<td>{$vars|debug_print_var nofilter}</td>
</tr>
{/foreach}
<td><h3><font color=blue>${$vars@key}</font></h3>
{if isset($vars['nocache'])}<b>Nocache</b></br>{/if}
{if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']|debug_print_var nofilter}{/if}
</td>
<td><h3>Value</h3>{$vars['value']|debug_print_var:10:80 nofilter}</td>
<td>{if isset($vars['attributes'])}<h3>Attributes</h3>{$vars['attributes']|debug_print_var nofilter} {/if}</td>
{/foreach}
</table>
<h2>assigned config file variables (outer template scope)</h2>
<h2>assigned config file variables</h2>
<table id="table_config_vars">
{foreach $config_vars as $vars}
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
<th>{$vars@key|escape:'html'}</th>
<td>{$vars|debug_print_var nofilter}</td>
<td><h3><font color=blue>#{$vars@key}#</font></h3>
{if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']|debug_print_var nofilter}{/if}
</td>
<td>{$vars['value']|debug_print_var:10:80 nofilter}</td>
</tr>
{/foreach}
@@ -130,8 +152,9 @@
</html>
{/capture}
<script type="text/javascript">
{$id = $template_name|default:''|md5}
_smarty_console = window.open("", "console{$id}", "width=680,height=600,resizable,scrollbars=yes");
{$id = '__Smarty__'}
{if $display_mode}{$id = "$offset$template_name"|md5}{/if}
_smarty_console = window.open("", "console{$id}", "width=1024,height=600,left={$offset},top={$offset},resizable,scrollbars=yes");
_smarty_console.document.write("{$debug_output|escape:'javascript' nofilter}");
_smarty_console.document.close();
</script>
+1 -1
View File
@@ -33,7 +33,7 @@ function smarty_modifier_date_format($string, $format = null, $default_date = ''
$format = Smarty::$_DATE_FORMAT;
}
/**
* Include the {@link shared.make_timestamp.php} plugin
* require_once the {@link shared.make_timestamp.php} plugin
*/
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') {
+22 -10
View File
@@ -14,26 +14,30 @@
*
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param array|object $var variable to be formatted
* @param integer $depth maximum recursion depth if $var is an array
* @param integer $length maximum string length if $var is a string
* @param array|object $var variable to be formatted
* @param int $max maximum recursion depth if $var is an array or object
* @param int $length maximum string length if $var is a string
* @param int $depth actual recursion depth
* @param array $objects processed objects in actual depth to prevent recursive object processing
*
* @return string
*/
function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
function smarty_modifier_debug_print_var($var, $max = 10, $length = 40, $depth = 0, $objects = array())
{
$_replace = array("\n" => '<i>\n</i>',
"\r" => '<i>\r</i>',
"\t" => '<i>\t</i>'
$_replace = array("\n" => '\n',
"\r" => '\r',
"\t" => '\t'
);
switch (gettype($var)) {
case 'array' :
$results = '<b>Array (' . count($var) . ')</b>';
if ($depth == $max) {
break;
}
foreach ($var as $curr_key => $curr_val) {
$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
. '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
. smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
. smarty_modifier_debug_print_var($curr_val, $max, $length, ++ $depth, $objects);
$depth --;
}
break;
@@ -41,10 +45,18 @@ function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
case 'object' :
$object_vars = get_object_vars($var);
$results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
if (in_array($var, $objects)) {
$results .= ' called recursive';
break;
}
if ($depth == $max) {
break;
}
$objects[] = $var;
foreach ($object_vars as $curr_key => $curr_val) {
$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
. '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
. smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
. smarty_modifier_debug_print_var($curr_val, $max, $length, ++ $depth, $objects);
$depth --;
}
break;
+3 -2
View File
@@ -19,10 +19,11 @@
* @param string $string input string
* @param string|array $search regular expression(s) to search for
* @param string|array $replace string(s) that should be replaced
* @param int $limit the maximum number of replacements
*
* @return string
*/
function smarty_modifier_regex_replace($string, $search, $replace)
function smarty_modifier_regex_replace($string, $search, $replace, $limit = -1)
{
if (is_array($search)) {
foreach ($search as $idx => $s) {
@@ -32,7 +33,7 @@ function smarty_modifier_regex_replace($string, $search, $replace)
$search = _smarty_regex_replace_check($search);
}
return preg_replace($search, $replace, $string);
return preg_replace($search, $replace, $string, $limit);
}
/**
+4 -4
View File
@@ -115,11 +115,11 @@ function smarty_modifiercompiler_escape($params, $compiler)
// could not optimize |escape call, so fallback to regular plugin
if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) {
$compiler->template->required_plugins['nocache']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'modifier.escape.php';
$compiler->template->required_plugins['nocache']['escape']['modifier']['function'] = 'smarty_modifier_escape';
$compiler->parent_compiler->template->compiled->required_plugins['nocache']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'modifier.escape.php';
$compiler->parent_compiler->template->compiled->required_plugins['nocache']['escape']['modifier']['function'] = 'smarty_modifier_escape';
} else {
$compiler->template->required_plugins['compiled']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'modifier.escape.php';
$compiler->template->required_plugins['compiled']['escape']['modifier']['function'] = 'smarty_modifier_escape';
$compiler->parent_compiler->template->compiled->required_plugins['compiled']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'modifier.escape.php';
$compiler->parent_compiler->template->compiled->required_plugins['compiled']['escape']['modifier']['function'] = 'smarty_modifier_escape';
}
return 'smarty_modifier_escape(' . join(', ', $params) . ')';
+1 -1
View File
@@ -12,7 +12,7 @@
* Name: strip_tags<br>
* Purpose: strip html tags from text
*
* @link http://www.smarty.net/manual/en/language.modifier.strip.tags.php strip_tags (Smarty online manual)
* @link http://www.smarty.net/docs/en/language.modifier.strip.tags.tpl strip_tags (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
+3 -3
View File
@@ -34,11 +34,11 @@ function smarty_modifiercompiler_wordwrap($params, $compiler)
$function = 'wordwrap';
if (Smarty::$_MBSTRING) {
if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) {
$compiler->template->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php';
$compiler->parent_compiler->template->compiled->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php';
$compiler->template->required_plugins['nocache']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
} else {
$compiler->template->required_plugins['compiled']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php';
$compiler->template->required_plugins['compiled']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
$compiler->parent_compiler->template->compiled->required_plugins['compiled']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php';
$compiler->parent_compiler->template->compiled->required_plugins['compiled']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
}
$function = 'smarty_mb_wordwrap';
}
+2 -2
View File
@@ -45,7 +45,7 @@ function smarty_outputfilter_trimwhitespace($source)
// capture html elements not to be messed with
$_offset = 0;
if (preg_match_all('#<(script|pre|textarea)[^>]*>.*?</\\1>#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
if (preg_match_all('#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
foreach ($matches as $match) {
$store[] = $match[0][0];
$_length = strlen($match[0][0]);
@@ -62,7 +62,7 @@ function smarty_outputfilter_trimwhitespace($source)
// can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
'#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
// remove spaces between attributes (but not in attribute values!)
'#(([a-z0-9]\s*=\s*(["\'])[^\3]*?\3)|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \4',
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
// note: for some very weird reason trim() seems to remove spaces inside attributes.
// maybe a \0 byte or something is interfering?
'#^\s+<#Ss' => '<',
+2 -2
View File
@@ -21,8 +21,8 @@ function smarty_make_timestamp($string)
if (empty($string)) {
// use "now":
return time();
} elseif ($string instanceof DateTime) {
return $string->getTimestamp();
} elseif ($string instanceof DateTime || (interface_exists('DateTimeInterface', false) && $string instanceof DateTimeInterface)) {
return (int) $string->format('U'); // PHP 5.2 BC
} elseif (strlen($string) == 14 && ctype_digit($string)) {
// it is mysql timestamp format of YYYYMMDDHHMMSS?
return mktime(substr($string, 8, 2), substr($string, 10, 2), substr($string, 12, 2),
+18 -234
View File
@@ -15,21 +15,12 @@
*/
abstract class Smarty_CacheResource
{
/**
* cache for Smarty_CacheResource instances
*
* @var array
*/
public static $resources = array();
/**
* resource types provided by the core
*
* @var array
*/
protected static $sysplugins = array(
'file' => true,
);
protected static $sysplugins = array('file' => 'smarty_internal_cacheresource_file.php',);
/**
* populate Cached Object with meta data from Resource
@@ -55,10 +46,11 @@ abstract class Smarty_CacheResource
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @param bool $update flag if called because cache update
*
* @return boolean true or false if the cached content does not exist
* @return bool true or false if the cached content does not exist
*/
abstract public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null);
abstract public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null, $update = false);
/**
* Write the rendered template output to cache
@@ -81,8 +73,8 @@ abstract class Smarty_CacheResource
{
if ($_template->cached->handler->process($_template)) {
ob_start();
$_template->properties['unifunc']($_template);
$unifunc = $_template->cached->unifunc;
$unifunc($_template);
return ob_get_clean();
}
@@ -193,32 +185,24 @@ abstract class Smarty_CacheResource
}
// try smarty's cache
if (isset($smarty->_cacheresource_handlers[$type])) {
return $smarty->_cacheresource_handlers[$type];
if (isset($smarty->_cache['cacheresource_handlers'][$type])) {
return $smarty->_cache['cacheresource_handlers'][$type];
}
// try registered resource
if (isset($smarty->registered_cache_resources[$type])) {
// do not cache these instances as they may vary from instance to instance
return $smarty->_cacheresource_handlers[$type] = $smarty->registered_cache_resources[$type];
return $smarty->_cache['cacheresource_handlers'][$type] = $smarty->registered_cache_resources[$type];
}
// try sysplugins dir
if (isset(self::$sysplugins[$type])) {
if (!isset(self::$resources[$type])) {
$cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type);
self::$resources[$type] = new $cache_resource_class();
}
return $smarty->_cacheresource_handlers[$type] = self::$resources[$type];
$cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type);
return $smarty->_cache['cacheresource_handlers'][$type] = new $cache_resource_class();
}
// try plugins dir
$cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type);
if ($smarty->loadPlugin($cache_resource_class)) {
if (!isset(self::$resources[$type])) {
self::$resources[$type] = new $cache_resource_class();
}
return $smarty->_cacheresource_handlers[$type] = self::$resources[$type];
return $smarty->_cache['cacheresource_handlers'][$type] = new $cache_resource_class();
}
// give up
throw new SmartyException("Unable to load cache resource '{$type}'");
@@ -229,214 +213,14 @@ abstract class Smarty_CacheResource
*
* @param Smarty $smarty Smarty object
*/
public static function invalidLoadedCache(Smarty $smarty)
public function invalidLoadedCache(Smarty $smarty)
{
foreach ($smarty->template_objects as $tpl) {
if (isset($tpl->cached)) {
$tpl->cached->valid = false;
$tpl->cached->processed = false;
if (isset($smarty->_cache['template_objects'])) {
foreach ($smarty->_cache['template_objects'] as $key => $tpl) {
if (isset($tpl->cached)) {
unset ($smarty->_cache['template_objects'][$key]);
}
}
}
}
}
/**
* Smarty Resource Data Object
* Cache Data Container for Template Files
*
* @package Smarty
* @subpackage TemplateResources
* @author Rodney Rehm
*/
class Smarty_Template_Cached
{
/**
* Source Filepath
*
* @var string
*/
public $filepath = false;
/**
* Source Content
*
* @var string
*/
public $content = null;
/**
* Source Timestamp
*
* @var integer
*/
public $timestamp = false;
/**
* Source Existence
*
* @var boolean
*/
public $exists = false;
/**
* Cache Is Valid
*
* @var boolean
*/
public $valid = false;
/**
* Cache was processed
*
* @var boolean
*/
public $processed = false;
/**
* CacheResource Handler
*
* @var Smarty_CacheResource
*/
public $handler = null;
/**
* Template Compile Id (Smarty_Internal_Template::$compile_id)
*
* @var string
*/
public $compile_id = null;
/**
* Template Cache Id (Smarty_Internal_Template::$cache_id)
*
* @var string
*/
public $cache_id = null;
/**
* Id for cache locking
*
* @var string
*/
public $lock_id = null;
/**
* flag that cache is locked by this instance
*
* @var bool
*/
public $is_locked = false;
/**
* Source Object
*
* @var Smarty_Template_Source
*/
public $source = null;
/**
* create Cached Object container
*
* @param Smarty_Internal_Template $_template template object
*/
public function __construct(Smarty_Internal_Template $_template)
{
$this->compile_id = $_template->compile_id;
$this->cache_id = $_template->cache_id;
$this->source = $_template->source;
$_template->cached = $this;
$smarty = $_template->smarty;
//
// load resource handler
//
$this->handler = $handler = Smarty_CacheResource::load($smarty); // Note: prone to circular references
//
// check if cache is valid
//
if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || $_template->source->recompiled) {
$handler->populate($this, $_template);
return;
}
while (true) {
while (true) {
$handler->populate($this, $_template);
if ($this->timestamp === false || $smarty->force_compile || $smarty->force_cache) {
$this->valid = false;
} else {
$this->valid = true;
}
if ($this->valid && $_template->caching == Smarty::CACHING_LIFETIME_CURRENT && $_template->cache_lifetime >= 0 && time() > ($this->timestamp + $_template->cache_lifetime)) {
// lifetime expired
$this->valid = false;
}
if ($this->valid || !$_template->smarty->cache_locking) {
break;
}
if (!$this->handler->locked($_template->smarty, $this)) {
$this->handler->acquireLock($_template->smarty, $this);
break 2;
}
}
if ($this->valid) {
if (!$_template->smarty->cache_locking || $this->handler->locked($_template->smarty, $this) === null) {
// load cache file for the following checks
if ($smarty->debugging) {
Smarty_Internal_Debug::start_cache($_template);
}
if ($handler->process($_template, $this) === false) {
$this->valid = false;
} else {
$this->processed = true;
}
if ($smarty->debugging) {
Smarty_Internal_Debug::end_cache($_template);
}
} else {
continue;
}
} else {
return;
}
if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED && $_template->properties['cache_lifetime'] >= 0 && (time() > ($_template->cached->timestamp + $_template->properties['cache_lifetime']))) {
$this->valid = false;
}
if (!$this->valid && $_template->smarty->cache_locking) {
$this->handler->acquireLock($_template->smarty, $this);
return;
} else {
return;
}
}
}
/**
* Write this cache object to handler
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content to cache
*
* @return boolean success
*/
public function write(Smarty_Internal_Template $_template, $content)
{
if (!$_template->source->recompiled) {
if ($this->handler->writeCachedContent($_template, $content)) {
$this->content = null;
$this->timestamp = time();
$this->exists = true;
$this->valid = true;
if ($_template->smarty->cache_locking) {
$this->handler->releaseLock($_template->smarty, $this);
}
return true;
}
}
return false;
}
}
+48 -51
View File
@@ -83,9 +83,12 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
{
$_cache_id = isset($cached->cache_id) ? preg_replace('![^\w\|]+!', '_', $cached->cache_id) : null;
$_compile_id = isset($cached->compile_id) ? preg_replace('![^\w\|]+!', '_', $cached->compile_id) : null;
$cached->filepath = sha1($cached->source->filepath . $_cache_id . $_compile_id);
$_compile_id = isset($cached->compile_id) ? preg_replace('![^\w]+!', '_', $cached->compile_id) : null;
$path = $cached->source->filepath . $_cache_id . $_compile_id;
$cached->filepath = sha1($path);
if ($_template->smarty->cache_locking) {
$cached->lock_id = sha1('lock.' . $path);
}
$this->populateTimestamp($cached);
}
@@ -116,10 +119,11 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @param bool $update flag if called because cache update
*
* @return boolean true or false if the cached content does not exist
*/
public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null)
public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null, $update = false)
{
if (!$cached) {
$cached = $_template->cached;
@@ -127,14 +131,7 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
$content = $cached->content ? $cached->content : null;
$timestamp = $cached->timestamp ? $cached->timestamp : null;
if ($content === null || !$timestamp) {
$this->fetch(
$_template->cached->filepath,
$_template->source->name,
$_template->cache_id,
$_template->compile_id,
$content,
$timestamp
);
$this->fetch($_template->cached->filepath, $_template->source->name, $_template->cache_id, $_template->compile_id, $content, $timestamp);
}
if (isset($content)) {
/** @var Smarty_Internal_Template $_smarty_tpl
@@ -142,7 +139,7 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
*/
$_smarty_tpl = $_template;
eval("?>" . $content);
$cached->content = null;
return true;
}
@@ -159,14 +156,28 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
*/
public function writeCachedContent(Smarty_Internal_Template $_template, $content)
{
return $this->save(
$_template->cached->filepath,
$_template->source->name,
$_template->cache_id,
$_template->compile_id,
$_template->properties['cache_lifetime'],
$content
);
return $this->save($_template->cached->filepath, $_template->source->name, $_template->cache_id, $_template->compile_id, $_template->cache_lifetime, $content);
}
/**
* Read cached template from cache
*
* @param Smarty_Internal_Template $_template template object
*
* @return string content
*/
public function readCachedContent(Smarty_Internal_Template $_template)
{
$content = $_template->cached->content ? $_template->cached->content : null;
$timestamp = null;
if ($content === null) {
$timestamp = null;
$this->fetch($_template->cached->filepath, $_template->source->name, $_template->cache_id, $_template->compile_id, $content, $timestamp);
}
if (isset($content)) {
return $content;
}
return false;
}
/**
@@ -179,8 +190,6 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
*/
public function clearAll(Smarty $smarty, $exp_time = null)
{
$this->cache = array();
return $this->delete(null, null, null, $exp_time);
}
@@ -197,32 +206,23 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
*/
public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
{
$this->cache = array();
$cache_name = null;
if (isset($resource_name)) {
$_save_stat = $smarty->caching;
$smarty->caching = true;
$tpl = new $smarty->template_class($resource_name, $smarty);
$smarty->caching = $_save_stat;
if ($tpl->source->exists) {
$cache_name = $tpl->source->name;
$source = Smarty_Template_Source::load(null, $smarty, $resource_name);
if ($source->exists) {
$cache_name = $source->name;
} else {
return 0;
}
// remove from template cache
if ($smarty->allow_ambiguous_resources) {
$_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
} else {
$_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
if (isset($smarty->_cache['template_objects'])) {
foreach ($smarty->_cache['template_objects'] as $key => $_tpl) {
if (isset($_tpl->cached) && $_tpl->source->uid == $source->uid) {
unset($smarty->_cache['template_objects'][$key]);
}
}
}
if (isset($_templateId[150])) {
$_templateId = sha1($_templateId);
}
unset($smarty->template_objects[$_templateId]);
// template object no longer needed
unset($tpl);
}
return $this->delete($cache_name, $cache_id, $compile_id, $exp_time);
@@ -238,15 +238,14 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
*/
public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$id = $cached->filepath;
$id = $cached->lock_id;
$name = $cached->source->name . '.lock';
$mtime = $this->fetchTimestamp($id, $name, null, null);
$mtime = $this->fetchTimestamp($id, $name, $cached->cache_id, $cached->compile_id);
if ($mtime === null) {
$this->fetch($id, $name, null, null, $content, $mtime);
$this->fetch($id, $name, $cached->cache_id, $cached->compile_id, $content, $mtime);
}
return $mtime && time() - $mtime < $smarty->locking_timeout;
return $mtime && ($t = time()) - $mtime < $smarty->locking_timeout;
}
/**
@@ -260,10 +259,9 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$cached->is_locked = true;
$id = $cached->filepath;
$id = $cached->lock_id;
$name = $cached->source->name . '.lock';
$this->save($id, $name, null, null, $smarty->locking_timeout, '');
$this->save($id, $name, $cached->cache_id, $cached->compile_id, $smarty->locking_timeout, '');
}
/**
@@ -277,8 +275,7 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$cached->is_locked = false;
$name = $cached->source->name . '.lock';
$this->delete($name, null, null, null);
$this->delete($name, $cached->cache_id, $cached->compile_id, null);
}
}
@@ -36,6 +36,7 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
* @var array
*/
protected $contents = array();
/**
* cache for timestamps
*
@@ -53,10 +54,8 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
*/
public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
{
$cached->filepath = $_template->source->uid
. '#' . $this->sanitize($cached->source->resource)
. '#' . $this->sanitize($cached->cache_id)
. '#' . $this->sanitize($cached->compile_id);
$cached->filepath = $_template->source->uid . '#' . $this->sanitize($cached->source->resource) . '#' .
$this->sanitize($cached->cache_id) . '#' . $this->sanitize($cached->compile_id);
$this->populateTimestamp($cached);
}
@@ -83,10 +82,11 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @param bool $update flag if called because cache update
*
* @return boolean true or false if the cached content does not exist
*/
public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null)
public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null, $update = false)
{
if (!$cached) {
$cached = $_template->cached;
@@ -123,7 +123,29 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
{
$this->addMetaTimestamp($content);
return $this->write(array($_template->cached->filepath => $content), $_template->properties['cache_lifetime']);
return $this->write(array($_template->cached->filepath => $content), $_template->cache_lifetime);
}
/**
* Read cached template from cache
*
* @param Smarty_Internal_Template $_template template object
*
* @return string content
*/
public function readCachedContent(Smarty_Internal_Template $_template)
{
$content = $_template->cached->content ? $_template->cached->content : null;
$timestamp = null;
if ($content === null) {
if (!$this->fetch($_template->cached->filepath, $_template->source->name, $_template->cache_id, $_template->compile_id, $content, $timestamp, $_template->source->uid)) {
return false;
}
}
if (isset($content)) {
return $content;
}
return false;
}
/**
@@ -142,7 +164,14 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
if (!$this->purge()) {
$this->invalidate(null);
}
// remove from template cache
if (isset($smarty->_cache['template_objects'])) {
foreach ($smarty->_cache['template_objects'] as $key => $tpl) {
if (isset($tpl->cached)) {
unset($smarty->_cache['template_objects'][$key]);
}
}
}
return - 1;
}
@@ -163,11 +192,21 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
*/
public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
{
$uid = $this->getTemplateUid($smarty, $resource_name, $cache_id, $compile_id);
$cid = $uid . '#' . $this->sanitize($resource_name) . '#' . $this->sanitize($cache_id) . '#' . $this->sanitize($compile_id);
$uid = $this->getTemplateUid($smarty, $resource_name);
$cid = $uid . '#' . $this->sanitize($resource_name) . '#' . $this->sanitize($cache_id) . '#' .
$this->sanitize($compile_id);
$this->delete(array($cid));
$this->invalidate($cid, $resource_name, $cache_id, $compile_id, $uid);
// remove from template cache
if (isset($resource_name) && isset($smarty->_cache['template_objects'])) {
if (isset($smarty->_cache['template_objects'])) {
foreach ($smarty->_cache['template_objects'] as $key => $tpl) {
if ($tpl->source->uid == $uid && isset($tpl->cached)) {
unset($smarty->_cache['template_objects'][$key]);
}
}
}
}
return - 1;
}
@@ -176,33 +215,20 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
*
* @param Smarty $smarty Smarty object
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
*
* @return string filepath of cache file
* @throws \SmartyException
*
*/
protected function getTemplateUid(Smarty $smarty, $resource_name, $cache_id, $compile_id)
protected function getTemplateUid(Smarty $smarty, $resource_name)
{
$uid = '';
if (isset($resource_name)) {
$tpl = new $smarty->template_class($resource_name, $smarty);
if ($tpl->source->exists) {
$uid = $tpl->source->uid;
$source = Smarty_Template_Source::load(null, $smarty, $resource_name);
if ($source->exists) {
return $source->uid;
}
// remove from template cache
if ($smarty->allow_ambiguous_resources) {
$_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
} else {
$_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
}
if (isset($_templateId[150])) {
$_templateId = sha1($_templateId);
}
unset($smarty->template_objects[$_templateId]);
}
return $uid;
return '';
}
/**
@@ -214,12 +240,10 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
*/
protected function sanitize($string)
{
// some poeple smoke bad weed
$string = trim($string, '|');
if (!$string) {
return null;
}
return preg_replace('#[^\w\|]+#S', '_', $string);
}
@@ -275,11 +299,8 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
*/
protected function getMetaTimestamp(&$content)
{
$s = unpack("N", substr($content, 0, 4));
$m = unpack("N", substr($content, 4, 4));
$content = substr($content, 8);
return $s[1] + ($m[1] / 100000000);
extract(unpack('N1s/N1m/a*content', $content));
return $s + ($m / 100000000);
}
/**
@@ -380,7 +401,6 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
$t[] = 'IVK#COMPILE' . $_compile;
}
$_name .= '#';
// some poeple smoke bad weed
$cid = trim($cache_id, '|');
if (!$cid) {
return $t;
-94
View File
@@ -1,94 +0,0 @@
<?php
/**
* Smarty Internal Plugin
*
* @package Smarty
* @subpackage TemplateResources
*/
/**
* Smarty Resource Data Object
* Meta Data Container for Config Files
*
* @package Smarty
* @subpackage TemplateResources
* @author Rodney Rehm
* @property string $content
* @property int $timestamp
* @property bool $exists
*/
class Smarty_Config_Source extends Smarty_Template_Source
{
/**
* create Config Object container
*
* @param Smarty_Resource $handler Resource Handler this source object communicates with
* @param Smarty $smarty Smarty instance this source object belongs to
* @param string $resource full config_resource
* @param string $type type of resource
* @param string $name resource name
* @param string $unique_resource unqiue resource name
*/
public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name, $unique_resource)
{
$this->handler = $handler; // Note: prone to circular references
// Note: these may be ->config_compiler_class etc in the future
//$this->config_compiler_class = $handler->config_compiler_class;
//$this->config_lexer_class = $handler->config_lexer_class;
//$this->config_parser_class = $handler->config_parser_class;
$this->smarty = $smarty;
$this->resource = $resource;
$this->type = $type;
$this->name = $name;
$this->unique_resource = $unique_resource;
}
/**
* <<magic>> Generic setter.
*
* @param string $property_name valid: content, timestamp, exists
* @param mixed $value newly assigned value (not check for correct type)
*
* @throws SmartyException when the given property name is not valid
*/
public function __set($property_name, $value)
{
switch ($property_name) {
case 'content':
case 'timestamp':
case 'exists':
$this->$property_name = $value;
break;
default:
throw new SmartyException("invalid config property '$property_name'.");
}
}
/**
* <<magic>> Generic getter.
*
* @param string $property_name valid: content, timestamp, exists
*
* @return mixed|void
* @throws SmartyException when the given property name is not valid
*/
public function __get($property_name)
{
switch ($property_name) {
case 'timestamp':
case 'exists':
$this->handler->populateTimestamp($this);
return $this->$property_name;
case 'content':
return $this->content = $this->handler->getContent($this);
default:
throw new SmartyException("config property '$property_name' does not exist.");
}
}
}
+68
View File
@@ -0,0 +1,68 @@
<?php
/**
* Smarty Plugin Data
* This file contains the data object
*
* @package Smarty
* @subpackage Template
* @author Uwe Tews
*/
/**
* class for the Smarty data object
* The Smarty data object will hold Smarty variables in the current scope
*
* @package Smarty
* @subpackage Template
*/
class Smarty_Data extends Smarty_Internal_Data
{
/**
* Counter
*
* @var int
*/
static $count = 0;
/**
* Data block name
*
* @var string
*/
public $dataObjectName = '';
/**
* Smarty object
*
* @var Smarty
*/
public $smarty = null;
/**
* create Smarty data object
*
* @param Smarty|array $_parent parent template
* @param Smarty|Smarty_Internal_Template $smarty global smarty instance
* @param string $name optional data block name
*
* @throws SmartyException
*/
public function __construct($_parent = null, $smarty = null, $name = null)
{
parent::__construct();
self::$count ++;
$this->dataObjectName = 'Data_object ' . (isset($name) ? "'{$name}'" : self::$count);
$this->smarty = $smarty;
if (is_object($_parent)) {
// when object set up back pointer
$this->parent = $_parent;
} elseif (is_array($_parent)) {
// set up variable values
foreach ($_parent as $_key => $_val) {
$this->tpl_vars[$_key] = new Smarty_Variable($_val);
}
} elseif ($_parent != null) {
throw new SmartyException("Wrong type for template variables");
}
}
}
@@ -29,14 +29,12 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource
{
$_source_file_path = str_replace(':', '.', $_template->source->filepath);
$_cache_id = isset($_template->cache_id) ? preg_replace('![^\w\|]+!', '_', $_template->cache_id) : null;
$_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
$_compile_id = isset($_template->compile_id) ? preg_replace('![^\w]+!', '_', $_template->compile_id) : null;
$_filepath = $_template->source->uid;
// if use_sub_dirs, break file into directories
if ($_template->smarty->use_sub_dirs) {
$_filepath = substr($_filepath, 0, 2) . DS
. substr($_filepath, 2, 2) . DS
. substr($_filepath, 4, 2) . DS
. $_filepath;
$_filepath = substr($_filepath, 0, 2) . DS . substr($_filepath, 2, 2) . DS . substr($_filepath, 4, 2) . DS .
$_filepath;
}
$_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
if (isset($_cache_id)) {
@@ -60,9 +58,12 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource
}
$cached->lock_id = $_lock_dir . sha1($_cache_id . $_compile_id . $_template->source->uid) . '.lock';
}
$cached->filepath = $_cache_dir . $_cache_id . $_compile_id . $_filepath . '.' . basename($_source_file_path) . '.php';
$cached->timestamp = @filemtime($cached->filepath);
$cached->exists = !!$cached->timestamp;
$cached->filepath = $_cache_dir . $_cache_id . $_compile_id . $_filepath . '.' . basename($_source_file_path) .
'.php';
$cached->timestamp = $cached->exists = is_file($cached->filepath);
if ($cached->exists) {
$cached->timestamp = filemtime($cached->filepath);
}
}
/**
@@ -74,8 +75,10 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource
*/
public function populateTimestamp(Smarty_Template_Cached $cached)
{
$cached->timestamp = @filemtime($cached->filepath);
$cached->exists = !!$cached->timestamp;
$cached->timestamp = $cached->exists = is_file($cached->filepath);
if ($cached->exists) {
$cached->timestamp = filemtime($cached->filepath);
}
}
/**
@@ -83,17 +86,22 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @param bool $update flag if called because cache update
*
* @return booleantrue or false if the cached content does not exist
* @return boolean true or false if the cached content does not exist
*/
public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null)
public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null, $update = false)
{
/** @var Smarty_Internal_Template $_smarty_tpl
* used in included file
*/
$_smarty_tpl = $_template;
return @include $_template->cached->filepath;
$_template->cached->valid = false;
if ($update && defined('HHVM_VERSION')) {
return $_template->smarty->ext->_hhvm->includeHhvm($_template, $_template->cached->filepath);
} else {
return @include $_template->cached->filepath;
}
}
/**
@@ -106,14 +114,32 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource
*/
public function writeCachedContent(Smarty_Internal_Template $_template, $content)
{
if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) {
$_template->cached->timestamp = @filemtime($_template->cached->filepath);
$_template->cached->exists = !!$_template->cached->timestamp;
if ($_template->cached->exists) {
if ($_template->smarty->ext->_writeFile->writeFile($_template->cached->filepath, $content, $_template->smarty) === true) {
if (function_exists('opcache_invalidate')) {
opcache_invalidate($_template->cached->filepath);
}
$cached = $_template->cached;
$cached->timestamp = $cached->exists = is_file($cached->filepath);
if ($cached->exists) {
$cached->timestamp = filemtime($cached->filepath);
return true;
}
}
return false;
}
/**
* Read cached template from cache
*
* @param Smarty_Internal_Template $_template template object
*
* @return string content
*/
public function readCachedContent(Smarty_Internal_Template $_template)
{
if (is_file($_template->cached->filepath)) {
return file_get_contents($_template->cached->filepath);
}
return false;
}
@@ -127,7 +153,7 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource
*/
public function clearAll(Smarty $smarty, $exp_time = null)
{
return $this->clear($smarty, null, null, null, $exp_time);
return Smarty_Internal_Extension_Clear::clear($smarty, null, null, null, $exp_time);
}
/**
@@ -143,108 +169,7 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource
*/
public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
{
$_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
$_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
$_dir_sep = $smarty->use_sub_dirs ? '/' : '^';
$_compile_id_offset = $smarty->use_sub_dirs ? 3 : 0;
if (($_dir = realpath($smarty->getCacheDir())) === false) {
return 0;
}
$_dir .= '/';
$_dir_length = strlen($_dir);
if (isset($_cache_id)) {
$_cache_id_parts = explode('|', $_cache_id);
$_cache_id_parts_count = count($_cache_id_parts);
if ($smarty->use_sub_dirs) {
foreach ($_cache_id_parts as $id_part) {
$_dir .= $id_part . DS;
}
}
}
if (isset($resource_name)) {
$_save_stat = $smarty->caching;
$smarty->caching = true;
$tpl = new $smarty->template_class($resource_name, $smarty);
$smarty->caching = $_save_stat;
// remove from template cache
$tpl->source; // have the template registered before unset()
if ($smarty->allow_ambiguous_resources) {
$_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
} else {
$_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
}
if (isset($_templateId[150])) {
$_templateId = sha1($_templateId);
}
unset($smarty->template_objects[$_templateId]);
if ($tpl->source->exists) {
$_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath));
} else {
return 0;
}
}
$_count = 0;
$_time = time();
if (file_exists($_dir)) {
$_cacheDirs = new RecursiveDirectoryIterator($_dir);
$_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($_cache as $_file) {
if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) {
continue;
}
// directory ?
if ($_file->isDir()) {
if (!$_cache->isDot()) {
// delete folder if empty
@rmdir($_file->getPathname());
}
} else {
$_parts = explode($_dir_sep, str_replace('\\', '/', substr((string) $_file, $_dir_length)));
$_parts_count = count($_parts);
// check name
if (isset($resource_name)) {
if ($_parts[$_parts_count - 1] != $_resourcename_parts) {
continue;
}
}
// check compile id
if (isset($_compile_id) && (!isset($_parts[$_parts_count - 2 - $_compile_id_offset]) || $_parts[$_parts_count - 2 - $_compile_id_offset] != $_compile_id)) {
continue;
}
// check cache id
if (isset($_cache_id)) {
// count of cache id parts
$_parts_count = (isset($_compile_id)) ? $_parts_count - 2 - $_compile_id_offset : $_parts_count - 1 - $_compile_id_offset;
if ($_parts_count < $_cache_id_parts_count) {
continue;
}
for ($i = 0; $i < $_cache_id_parts_count; $i ++) {
if ($_parts[$i] != $_cache_id_parts[$i]) {
continue 2;
}
}
}
// expired ?
if (isset($exp_time)) {
if ($exp_time < 0) {
preg_match('#\'cache_lifetime\' =>\s*(\d*)#', file_get_contents($_file), $match);
if ($_time < (@filemtime($_file) + $match[1])) {
continue;
}
} else {
if ($_time - @filemtime($_file) < $exp_time) {
continue;
}
}
}
$_count += @unlink((string) $_file) ? 1 : 0;
}
}
}
return $_count;
return Smarty_Internal_Extension_Clear::clear($smarty, $resource_name, $cache_id, $compile_id, $exp_time);
}
/**
@@ -262,9 +187,12 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource
} else {
clearstatcache();
}
$t = @filemtime($cached->lock_id);
return $t && (time() - $t < $smarty->locking_timeout);
if (is_file($cached->lock_id)) {
$t = @filemtime($cached->lock_id);
return $t && (time() - $t < $smarty->locking_timeout);
} else {
return false;
}
}
/**
@@ -19,13 +19,13 @@ class Smarty_Internal_Compile_Append extends Smarty_Internal_Compile_Assign
/**
* Compiles code for the {append} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// the following must be assigned at runtime because it will be overwritten in parent class
$this->required_attributes = array('var', 'value');
@@ -16,23 +16,31 @@
*/
class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase
{
/**
* Valid scope names
*
* @var array
*/
public $valid_scopes = array('local' => true, 'parent' => true, 'root' => true, 'global' => true,
'smarty' => true, 'tpl_root' => true);
/**
* Compiles code for the {assign} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// the following must be assigned at runtime because it will be overwritten in Smarty_Internal_Compile_Append
$this->required_attributes = array('var', 'value');
$this->shorttag_order = array('var', 'value');
$this->optional_attributes = array('scope');
$this->optional_attributes = array('scope', 'bubble_up');
$_nocache = 'null';
$_scope = Smarty::SCOPE_LOCAL;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// nocache ?
@@ -42,43 +50,47 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase
if (isset($compiler->template->tpl_vars[trim($_attr['var'], "'")])) {
$compiler->template->tpl_vars[trim($_attr['var'], "'")]->nocache = true;
} else {
$compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_variable(null, true);
$compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_Variable(null, true);
}
}
// scope setup
$_scope = Smarty::SCOPE_LOCAL;
if (isset($_attr['scope'])) {
$_attr['scope'] = trim($_attr['scope'], "'\"");
if ($_attr['scope'] == 'parent') {
$_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr['scope'] == 'root') {
$_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr['scope'] == 'global') {
$_scope = Smarty::SCOPE_GLOBAL;
} else {
$compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno);
if (!isset($this->valid_scopes[$_attr['scope']])) {
$compiler->trigger_template_error("illegal value '{$_attr['scope']}' for \"scope\" attribute", null, true);
}
if ($_attr['scope'] != 'local') {
if ($_attr['scope'] == 'parent') {
$_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr['scope'] == 'root') {
$_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr['scope'] == 'global') {
$_scope = Smarty::SCOPE_GLOBAL;
} elseif ($_attr['scope'] == 'smarty') {
$_scope = Smarty::SCOPE_SMARTY;
} elseif ($_attr['scope'] == 'tpl_root') {
$_scope = Smarty::SCOPE_TPL_ROOT;
}
$_scope += (isset($_attr['bubble_up']) && $_attr['bubble_up'] == 'false') ? 0 : Smarty::SCOPE_BUBBLE_UP;
}
}
// compiled output
if (isset($parameter['smarty_internal_index'])) {
$output = "<?php \$_smarty_tpl->createLocalArrayVariable($_attr[var], $_nocache, $_scope);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];";
$output =
"<?php \$_smarty_tpl->smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, $_attr[var], $_nocache);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];";
} else {
// implement Smarty2's behaviour of variables assigned by reference
if ($compiler->template->smarty instanceof SmartyBC) {
$output = "<?php if (isset(\$_smarty_tpl->tpl_vars[$_attr[var]])) {\$_smarty_tpl->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
$output .= "\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value = $_attr[value]; \$_smarty_tpl->tpl_vars[$_attr[var]]->nocache = $_nocache; \$_smarty_tpl->tpl_vars[$_attr[var]]->scope = $_scope;";
$output .= "\n} else \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);";
$output =
"<?php if (isset(\$_smarty_tpl->tpl_vars[$_attr[var]])) {\$_smarty_tpl->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
$output .= "\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value = $_attr[value]; \$_smarty_tpl->tpl_vars[$_attr[var]]->nocache = $_nocache;";
$output .= "\n} else \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_Variable($_attr[value], $_nocache);";
} else {
$output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);";
$output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_Variable($_attr[value], $_nocache);";
}
}
if ($_scope == Smarty::SCOPE_PARENT) {
$output .= "\nif (\$_smarty_tpl->parent != null) \$_smarty_tpl->parent->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
} elseif ($_scope == Smarty::SCOPE_ROOT || $_scope == Smarty::SCOPE_GLOBAL) {
$output .= "\n\$_ptr = \$_smarty_tpl->parent; while (\$_ptr != null) {\$_ptr->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]]; \$_ptr = \$_ptr->parent; }";
}
if ($_scope == Smarty::SCOPE_GLOBAL) {
$output .= "\nSmarty::\$global_tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
}
$output .= "\n\$_smarty_tpl->ext->_updateScope->updateScope(\$_smarty_tpl, $_attr[var], $_scope);";
$output .= '?>';
return $output;
+194 -346
View File
@@ -1,24 +1,20 @@
<?php
/**
* Smarty Internal Plugin Compile Block
* Compiles the {block}{/block} tags
/*
* This file is part of Smarty.
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
* (c) 2015 Uwe Tews
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Smarty Internal Plugin Compile Block Class
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews <uwe.tews@googlemail.com>
*/
class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inheritance
{
const parent = '____SMARTY_BLOCK_PARENT____';
/**
* Attribute definition: Overwrites base class.
*
@@ -41,7 +37,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
* @var array
* @see Smarty_Internal_CompileBase
*/
public $option_flags = array('hide', 'append', 'prepend', 'nocache');
public $option_flags = array('hide', 'nocache');
/**
* Attribute definition: Overwrites base class.
@@ -49,396 +45,248 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('internal_file', 'internal_uid', 'internal_line');
/**
* nested child block names
*
* @var array
*/
public static $nested_block_names = array();
public $optional_attributes = array('assign');
/**
* child block source buffer
* nesting level of block tags
*
* @var array
* @var int
*/
public static $block_data = array();
public static $blockTagNestingLevel = 0;
/**
* Saved compiler object
*
* @var Smarty_Internal_TemplateCompilerBase
*/
public $compiler = null;
/**
* Compiles code for the {block} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return boolean true
* @return bool true
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
if (!isset($compiler->_cache['blockNesting'])) {
$compiler->_cache['blockNesting'] = 0;
}
if ($compiler->_cache['blockNesting'] == 0) {
// make sure that inheritance gets initialized in template code
$this->registerInit($compiler);
$this->option_flags = array('hide', 'nocache', 'append', 'prepend');
} else {
$this->option_flags = array('hide', 'nocache');
}
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$_name = trim($_attr['name'], "\"'");
// existing child must override parent settings
if (isset($compiler->template->block_data[$_name]) && $compiler->template->block_data[$_name]['mode'] == 'replace') {
$_attr['append'] = false;
$_attr['prepend'] = false;
$compiler->_cache['blockNesting'] ++;
$compiler->_cache['blockName'][$compiler->_cache['blockNesting']] = $_attr['name'];
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']][0] = 'block_' . preg_replace('![^\w]+!', '_', uniqid(rand(), true));
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']][1] = false;
$this->openTag($compiler, 'block', array($_attr, $compiler->nocache, $compiler->parser->current_buffer,
$compiler->template->compiled->has_nocache_code,
$compiler->template->caching));
// must whole block be nocache ?
if ($compiler->tag_nocache) {
$i = 0;
}
// check if we process an inheritance child template
if ($compiler->inheritance_child) {
array_unshift(self::$nested_block_names, $_name);
// build {block} for child block
self::$block_data[$_name]['source'] =
"{$compiler->smarty->left_delimiter}private_child_block name={$_attr['name']} file='{$compiler->template->source->filepath}' type='{$compiler->template->source->type}' resource='{$compiler->template->template_resource}'" .
" uid='{$compiler->template->source->uid}' line={$compiler->lex->line}";
if ($_attr['nocache']) {
self::$block_data[$_name]['source'] .= ' nocache';
}
self::$block_data[$_name]['source'] .= $compiler->smarty->right_delimiter;
$save = array($_attr, $compiler->inheritance);
$this->openTag($compiler, 'block', $save);
// set flag for {block} tag
$compiler->inheritance = true;
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
$compiler->has_code = false;
return;
}
// must merge includes
if ($_attr['nocache'] == true) {
$compiler->tag_nocache = true;
}
$save = array($_attr, $compiler->inheritance, $compiler->parser->current_buffer, $compiler->nocache);
$this->openTag($compiler, 'block', $save);
$compiler->inheritance = true;
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
$compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
$compiler->has_code = false;
return true;
// $compiler->suppressNocacheProcessing = true;
if ($_attr['nocache'] === true) {
//$compiler->trigger_template_error('nocache option not allowed', $compiler->parser->lex->taglineno);
}
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
$compiler->template->compiled->has_nocache_code = false;
$compiler->suppressNocacheProcessing = true;
}
/**
* Compile saved child block source
*
* @param object $compiler compiler object
* @param string $_name optional name of child block
* @param \Smarty_Internal_TemplateCompilerBase compiler object
* @param string $_name optional name of child block
*
* @return string compiled code of child block
*/
static function compileChildBlock($compiler, $_name = null)
static function compileChildBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
{
if ($compiler->inheritance_child) {
$name1 = Smarty_Internal_Compile_Block::$nested_block_names[0];
if (isset($compiler->template->block_data[$name1])) {
// replace inner block name with generic
Smarty_Internal_Compile_Block::$block_data[$name1]['source'] .= $compiler->template->block_data[$name1]['source'];
Smarty_Internal_Compile_Block::$block_data[$name1]['child'] = true;
}
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
$compiler->has_code = false;
return;
if (!isset($compiler->_cache['blockNesting'])) {
$compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ',
$compiler->parser->lex->taglineno);
}
// if called by {$smarty.block.child} we must search the name of enclosing {block}
if ($_name == null) {
$stack_count = count($compiler->_tag_stack);
while (--$stack_count >= 0) {
if ($compiler->_tag_stack[$stack_count][0] == 'block') {
$_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "\"'");
break;
}
}
}
if ($_name == null) {
$compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ', $compiler->lex->taglineno);
}
// undefined child?
if (!isset($compiler->template->block_data[$_name]['source'])) {
$compiler->popTrace();
return '';
}
// flag that child is already compile by {$smarty.block.child} inclusion
$compiler->template->block_data[$_name]['compiled'] = true;
$_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
$compiler->template->compile_id, $compiler->template->caching, $compiler->template->cache_lifetime);
if ($compiler->smarty->debugging) {
Smarty_Internal_Debug::ignore($_tpl);
}
$_tpl->tpl_vars = $compiler->template->tpl_vars;
$_tpl->variable_filters = $compiler->template->variable_filters;
$_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
$_tpl->allow_relative_path = true;
$_tpl->compiler->inheritance = true;
$_tpl->compiler->suppressHeader = true;
$_tpl->compiler->suppressFilter = true;
$_tpl->compiler->suppressTemplatePropertyHeader = true;
$_tpl->compiler->suppressMergedTemplates = true;
$nocache = $compiler->nocache || $compiler->tag_nocache;
if (strpos($compiler->template->block_data[$_name]['source'], self::parent) !== false) {
$_output = str_replace(self::parent, $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl, $nocache));
} elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') {
$_output = $_tpl->compiler->compileTemplate($_tpl, $nocache) . $compiler->parser->current_buffer->to_smarty_php();
} elseif ($compiler->template->block_data[$_name]['mode'] == 'append') {
$_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl, $nocache);
} elseif (!empty($compiler->template->block_data[$_name])) {
$_output = $_tpl->compiler->compileTemplate($_tpl, $nocache);
}
$compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $_tpl->properties['file_dependency']);
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $_tpl->properties['function']);
$compiler->merged_templates = array_merge($compiler->merged_templates, $_tpl->compiler->merged_templates);
$compiler->template->variable_filters = $_tpl->variable_filters;
if ($_tpl->has_nocache_code) {
$compiler->template->has_nocache_code = true;
}
foreach ($_tpl->required_plugins as $key => $tmp1) {
if ($compiler->nocache && $compiler->template->caching) {
$code = 'nocache';
} else {
$code = $key;
}
foreach ($tmp1 as $name => $tmp) {
foreach ($tmp as $type => $data) {
$compiler->template->required_plugins[$code][$name][$type] = $data;
}
}
}
unset($_tpl);
$compiler->has_code = true;
return $_output;
$compiler->suppressNocacheProcessing = true;
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']][1] = true;
$output = "<?php \n\$_smarty_tpl->ext->_inheritance->processBlock(\$_smarty_tpl, 2, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, null, \$_blockParentStack);\n?>\n";
return $output;
}
/**
* Compile $smarty.block.parent
*
* @param object $compiler compiler object
* @param string $_name optional name of child block
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param string $_name optional name of child block
*
* @return string compiled code of child block
*/
static function compileParentBlock($compiler, $_name = null)
static function compileParentBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
{
// if called by {$smarty.block.parent} we must search the name of enclosing {block}
if ($_name == null) {
$stack_count = count($compiler->_tag_stack);
while (--$stack_count >= 0) {
if ($compiler->_tag_stack[$stack_count][0] == 'block') {
$_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "\"'");
break;
}
}
if (!isset($compiler->_cache['blockNesting'])) {
$compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ',
$compiler->parser->lex->taglineno);
}
if ($_name == null) {
$compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ', $compiler->lex->taglineno);
}
if (empty(Smarty_Internal_Compile_Block::$nested_block_names)) {
$compiler->trigger_template_error(' illegal {$smarty.block.parent} in parent template ', $compiler->lex->taglineno);
}
Smarty_Internal_Compile_Block::$block_data[Smarty_Internal_Compile_Block::$nested_block_names[0]]['source'] .= Smarty_Internal_Compile_Block::parent;
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
$compiler->has_code = false;
return;
}
/**
* Process block source
*
* @param $compiler
* @param string $source source text
*
*/
static function blockSource($compiler, $source)
{
Smarty_Internal_Compile_Block::$block_data[Smarty_Internal_Compile_Block::$nested_block_names[0]]['source'] .= $source;
$compiler->suppressNocacheProcessing = true;
$compiler->has_code = true;
$output = "<?php \n\$_smarty_tpl->ext->_inheritance->processBlock(\$_smarty_tpl, 3, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, null, \$_blockParentStack);\n?>\n";
return $output;
}
}
/**
* Smarty Internal Plugin Compile BlockClose Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_Inheritance
{
/**
* Compiles code for the {/block} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @return bool true
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
list($_attr, $_nocache, $_buffer, $_has_nocache_code, $_caching) = $this->closeTag($compiler, array('block'));
// init block parameter
$_block = $compiler->_cache['blockParams'][$compiler->_cache['blockNesting']];
unset($compiler->_cache['blockParams'][$compiler->_cache['blockNesting']]);
$_block[2] = $_block[3] = 0;
$_name = trim($_attr['name'], "'\"");
$_assign = isset($_attr['assign']) ? $_attr['assign'] : null;
unset($_attr['assign'], $_attr['name']);
foreach ($_attr as $name => $stat) {
if ((is_bool($stat) && $stat !== false) || (!is_bool($stat) && $stat != 'false')) {
$_block[$name] = is_string($stat) ? trim($stat, "'\"") : $stat;
}
}
$_funcName = $_block[0];
// get compiled block code
$_functionCode = $compiler->parser->current_buffer;
// setup buffer for template function code
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
if ($compiler->template->compiled->has_nocache_code) {
// $compiler->parent_compiler->template->tpl_function[$_name]['call_name_caching'] = $_funcNameCaching;
$_block[6] = $_funcNameCaching = $_funcName . '_nocache';
$output = "<?php\n";
$output .= "/* {block '{$_name}'} {$compiler->template->source->type}:{$compiler->template->source->name} */\n";
$output .= "function {$_funcNameCaching} (\$_smarty_tpl, \$_blockParentStack) {\n";
$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
$output .= "\$_smarty_tpl->cached->hashes['{$compiler->template->compiled->nocache_hash}'] = true;\n";
if (isset($_assign)) {
$output .= "ob_start();\n";
}
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Tag($compiler->parser,
$output));
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
$output = "<?php\n";
if (isset($_assign)) {
$output .= "\$_smarty_tpl->tpl_vars[{$_assign}] = new Smarty_Variable(ob_get_clean());\n";
}
$output .= "/*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
$output .= "}\n";
$output .= "/* {/block '{$_name}'} */\n\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Tag($compiler->parser,
$output));
$compiler->blockOrFunctionCode .= $f = $compiler->parser->current_buffer->to_smarty_php($compiler->parser);
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
$this->compiler = $compiler;
$_functionCode = new Smarty_Internal_ParseTree_Tag($compiler->parser,
preg_replace_callback("/((<\?php )?echo '\/\*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/([\S\s]*?)\/\*\/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/",
array($this, 'removeNocache'),
$_functionCode->to_smarty_php($compiler->parser)));
$this->compiler = null;
}
$output = "<?php\n";
$output .= "/* {block '{$_name}'} {$compiler->template->source->type}:{$compiler->template->source->name} */\n";
$output .= "function {$_funcName}(\$_smarty_tpl, \$_blockParentStack) {\n";
if (isset($_assign)) {
$output .= "ob_start();\n";
}
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Tag($compiler->parser,
$output));
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
$output = "<?php\n";
if (isset($_assign)) {
$output .= "\$_smarty_tpl->tpl_vars[{$_assign}] = new Smarty_Variable(ob_get_clean());\n";
}
$output .= "}\n";
$output .= "/* {/block '{$_name}'} */\n\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Tag($compiler->parser,
$output));
$compiler->blockOrFunctionCode .= $compiler->parser->current_buffer->to_smarty_php($compiler->parser);
// nocache plugins must be copied
if (!empty($compiler->template->compiled->required_plugins['nocache'])) {
foreach ($compiler->template->compiled->required_plugins['nocache'] as $plugin => $tmp) {
foreach ($tmp as $type => $data) {
$compiler->parent_compiler->template->compiled->required_plugins['compiled'][$plugin][$type] =
$data;
}
}
}
// restore old status
$compiler->template->compiled->has_nocache_code = $_has_nocache_code;
$compiler->tag_nocache = $compiler->nocache;
$compiler->nocache = $_nocache;
$compiler->parser->current_buffer = $_buffer;
$output = "<?php \n";
if ($compiler->_cache['blockNesting'] == 1) {
$output .= "\$_smarty_tpl->ext->_inheritance->processBlock(\$_smarty_tpl, 0, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, " .
var_export($_block, true) . ");\n";
} else {
$output .= "\$_smarty_tpl->ext->_inheritance->processBlock(\$_smarty_tpl, 0, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, " .
var_export($_block, true) . ", \$_blockParentStack);\n";
}
$output .= "?>\n";
$compiler->_cache['blockNesting'] --;
if ($compiler->_cache['blockNesting'] == 0) {
unset($compiler->_cache['blockNesting']);
}
$compiler->has_code = true;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$saved_data = $this->closeTag($compiler, array('block'));
$_name = trim($saved_data[0]['name'], "\"'");
// reset flag for {block} tag
$compiler->inheritance = $saved_data[1];
// check if we process an inheritance child template
if ($compiler->inheritance_child) {
$name1 = Smarty_Internal_Compile_Block::$nested_block_names[0];
Smarty_Internal_Compile_Block::$block_data[$name1]['source'] .= "{$compiler->smarty->left_delimiter}/private_child_block{$compiler->smarty->right_delimiter}";
array_shift(Smarty_Internal_Compile_Block::$nested_block_names);
if (!empty(Smarty_Internal_Compile_Block::$nested_block_names)) {
$name2 = Smarty_Internal_Compile_Block::$nested_block_names[0];
if (isset($compiler->template->block_data[$name1]) || !$saved_data[0]['hide']) {
if (isset(Smarty_Internal_Compile_Block::$block_data[$name1]['child']) || !isset($compiler->template->block_data[$name1])) {
Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
} else {
if ($compiler->template->block_data[$name1]['mode'] == 'append') {
Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'] . $compiler->template->block_data[$name1]['source'];
} elseif ($compiler->template->block_data[$name1]['mode'] == 'prepend') {
Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= $compiler->template->block_data[$name1]['source'] . Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
} else {
Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= $compiler->template->block_data[$name1]['source'];
}
}
}
unset(Smarty_Internal_Compile_Block::$block_data[$name1]);
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
} else {
if (isset($compiler->template->block_data[$name1]) || !$saved_data[0]['hide']) {
if (isset($compiler->template->block_data[$name1]) && !isset(Smarty_Internal_Compile_Block::$block_data[$name1]['child'])) {
if (strpos($compiler->template->block_data[$name1]['source'], Smarty_Internal_Compile_Block::parent) !== false) {
$compiler->template->block_data[$name1]['source'] =
str_replace(Smarty_Internal_Compile_Block::parent, Smarty_Internal_Compile_Block::$block_data[$name1]['source'], $compiler->template->block_data[$name1]['source']);
} elseif ($compiler->template->block_data[$name1]['mode'] == 'prepend') {
$compiler->template->block_data[$name1]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
} elseif ($compiler->template->block_data[$name1]['mode'] == 'append') {
$compiler->template->block_data[$name1]['source'] = Smarty_Internal_Compile_Block::$block_data[$name1]['source'] . $compiler->template->block_data[$name1]['source'];
}
} else {
$compiler->template->block_data[$name1]['source'] = Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
}
$compiler->template->block_data[$name1]['mode'] = 'replace';
if ($saved_data[0]['append']) {
$compiler->template->block_data[$name1]['mode'] = 'append';
}
if ($saved_data[0]['prepend']) {
$compiler->template->block_data[$name1]['mode'] = 'prepend';
}
}
unset(Smarty_Internal_Compile_Block::$block_data[$name1]);
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
}
$compiler->has_code = false;
return;
}
if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
$_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
} else {
if ($saved_data[0]['hide'] && !isset($compiler->template->block_data[$_name]['source'])) {
$_output = '';
} else {
$_output = $compiler->parser->current_buffer->to_smarty_php();
}
}
unset($compiler->template->block_data[$_name]['compiled']);
// reset flags
$compiler->parser->current_buffer = $saved_data[2];
if ($compiler->nocache) {
$compiler->tag_nocache = true;
}
$compiler->nocache = $saved_data[3];
// $_output content has already nocache code processed
$compiler->suppressNocacheProcessing = true;
return $_output;
return $output;
}
}
/**
* Smarty Internal Plugin Compile Child Block Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_Child_Block extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
* @param $match
*
* @var array
* @see Smarty_Internal_CompileBase
* @return mixed
*/
public $required_attributes = array('name', 'file', 'uid', 'line', 'type', 'resource');
/**
* Compiles code for the {private_child_block} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
*
* @return boolean true
*/
public function compile($args, $compiler)
function removeNocache($match)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// update template with original template resource of {block}
if (trim($_attr['type'], "'") == 'file') {
$compiler->template->template_resource = 'file:' . realpath(trim($_attr['file'], "'"));
} else {
$compiler->template->template_resource = trim($_attr['resource'], "'");
}
// source object
unset ($compiler->template->source);
$exists = $compiler->template->source->exists;
// must merge includes
if ($_attr['nocache'] == true) {
$compiler->tag_nocache = true;
}
$save = array($_attr, $compiler->nocache);
// set trace back to child block
$compiler->pushTrace(trim($_attr['file'], "\"'"), trim($_attr['uid'], "\"'"), $_attr['line'] - $compiler->lex->line);
$this->openTag($compiler, 'private_child_block', $save);
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
$compiler->has_code = false;
return true;
}
}
/**
* Smarty Internal Plugin Compile Child Block Close Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_Child_Blockclose extends Smarty_Internal_CompileBase
{
/**
* Compiles code for the {/private_child_block} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
*
* @return boolean true
*/
public function compile($args, $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$saved_data = $this->closeTag($compiler, array('private_child_block'));
// end of child block
$compiler->popTrace();
$compiler->nocache = $saved_data[1];
$compiler->has_code = false;
return true;
$code =
preg_replace("/((<\?php )?echo '\/\*%%SmartyNocache:{$this->compiler->template->compiled->nocache_hash}%%\*\/)|(\/\*\/%%SmartyNocache:{$this->compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/",
'', $match[0]);
$code = str_replace(array('\\\'', '\\\\\''), array('\'', '\\\''), $code);
return $code;
}
}
@@ -23,6 +23,7 @@ class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('levels');
/**
* Attribute definition: Overwrites base class.
*
@@ -34,25 +35,26 @@ class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase
/**
* Compiles code for the {break} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
$compiler->trigger_template_error('nocache option not allowed', null, true);
}
if (isset($_attr['levels'])) {
if (!is_numeric($_attr['levels'])) {
$compiler->trigger_template_error('level attribute must be a numeric constant', $compiler->lex->taglineno);
$compiler->trigger_template_error('level attribute must be a numeric constant', null, true);
}
$_levels = $_attr['levels'];
} else {
@@ -67,7 +69,7 @@ class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase
$stack_count --;
}
if ($level_count != 0) {
$compiler->trigger_template_error("cannot break {$_levels} level(s)", $compiler->lex->taglineno);
$compiler->trigger_template_error("cannot break {$_levels} level(s)", null, true);
}
return "<?php break {$_levels};?>";
@@ -23,6 +23,7 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('name');
/**
* Attribute definition: Overwrites base class.
*
@@ -30,6 +31,7 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name');
/**
* Attribute definition: Overwrites base class.
*
@@ -55,13 +57,11 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase
// output will be stored in a smarty variable instead of being displayed
$_assign = $_attr['assign'];
}
//$_name = trim($_attr['name'], "'\"");
$_name = $_attr['name'];
if ($compiler->compiles_template_function) {
$compiler->called_functions[] = trim($_name, "'\"");
}
unset($_attr['name'], $_attr['assign'], $_attr['nocache']);
// set flag (compiled code of {function} must be included in cache file
if ($compiler->nocache || $compiler->tag_nocache) {
if (!$compiler->template->caching || $compiler->nocache || $compiler->tag_nocache) {
$_nocache = 'true';
} else {
$_nocache = 'false';
@@ -74,54 +74,16 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase
$_paramsArray[] = "'$_key'=>$_value";
}
}
if (isset($compiler->template->properties['function'][$_name]['parameter'])) {
foreach ($compiler->template->properties['function'][$_name]['parameter'] as $_key => $_value) {
if (!isset($_attr[$_key])) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
}
} elseif (isset($compiler->smarty->template_functions[$_name]['parameter'])) {
foreach ($compiler->smarty->template_functions[$_name]['parameter'] as $_key => $_value) {
if (!isset($_attr[$_key])) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
}
}
//variable name?
if (!(strpos($_name, '$') === false)) {
$call_cache = $_name;
$call_function = '$tmp = "smarty_template_function_".' . $_name . '; $tmp';
} else {
$_name = trim($_name, "'\"");
$call_cache = "'{$_name}'";
$call_function = 'smarty_template_function_' . $_name;
}
$_params = 'array(' . implode(",", $_paramsArray) . ')';
$_hash = str_replace('-', '_', $compiler->template->properties['nocache_hash']);
//$compiler->suppressNocacheProcessing = true;
// was there an assign attribute
if (isset($_assign)) {
if ($compiler->template->caching) {
$_output = "<?php ob_start(); Smarty_Internal_Function_Call_Handler::call ({$call_cache},\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
} else {
$_output = "<?php ob_start(); {$call_function}(\$_smarty_tpl,{$_params}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
}
$_output =
"<?php ob_start();\n\$_smarty_tpl->smarty->ext->_tplFunction->callTemplateFunction(\$_smarty_tpl, {$_name}, {$_params}, {$_nocache});\n\$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
} else {
if ($compiler->template->caching) {
$_output = "<?php Smarty_Internal_Function_Call_Handler::call ({$call_cache},\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache});?>\n";
} else {
$_output = "<?php {$call_function}(\$_smarty_tpl,{$_params});?>\n";
}
$_output =
"<?php \$_smarty_tpl->smarty->ext->_tplFunction->callTemplateFunction(\$_smarty_tpl, {$_name}, {$_params}, {$_nocache});?>\n";
}
return $_output;
}
}
@@ -23,6 +23,7 @@ class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name');
/**
* Attribute definition: Overwrites base class.
*
@@ -34,12 +35,12 @@ class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase
/**
* Compiles code for the {capture} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string compiled code
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
@@ -51,10 +52,31 @@ class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase
$compiler->_capture_stack[0][] = array($buffer, $assign, $append, $compiler->nocache);
// maybe nocache because of nocache variables
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
$_output = "<?php \$_smarty_tpl->_capture_stack[0][] = array($buffer, $assign, $append); ob_start(); ?>";
$_output = "<?php \$_smarty_tpl->_cache['capture_stack'][] = array($buffer, $assign, $append); ob_start(); ?>";
return $_output;
}
/**
* Compiles code for the {$smarty.capture.xxx}
*
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public static function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// make all lower case
$parameter = array_map('strtolower', $parameter);
$tag = trim($parameter[0], '"\'');
if (!isset($parameter[1]) || false === $name = $compiler->getId($parameter[1])) {
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", null, true);
}
return "isset(\$_smarty_tpl->_cache['__smarty_capture']['{$name}']) ? \$_smarty_tpl->_cache['__smarty_capture']['{$name}'] : null";
}
}
/**
@@ -68,12 +90,12 @@ class Smarty_Internal_Compile_CaptureClose extends Smarty_Internal_CompileBase
/**
* Compiles code for the {/capture} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string compiled code
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
@@ -84,11 +106,11 @@ class Smarty_Internal_Compile_CaptureClose extends Smarty_Internal_CompileBase
list($buffer, $assign, $append, $compiler->nocache) = array_pop($compiler->_capture_stack[0]);
$_output = "<?php list(\$_capture_buffer, \$_capture_assign, \$_capture_append) = array_pop(\$_smarty_tpl->_capture_stack[0]);\n";
$_output = "<?php list(\$_capture_buffer, \$_capture_assign, \$_capture_append) = array_pop(\$_smarty_tpl->_cache['capture_stack']);\n";
$_output .= "if (!empty(\$_capture_buffer)) {\n";
$_output .= " if (isset(\$_capture_assign)) \$_smarty_tpl->assign(\$_capture_assign, ob_get_contents());\n";
$_output .= " if (isset( \$_capture_append)) \$_smarty_tpl->append( \$_capture_append, ob_get_contents());\n";
$_output .= " Smarty::\$_smarty_vars['capture'][\$_capture_buffer]=ob_get_clean();\n";
$_output .= "\$_smarty_tpl->_cache['__smarty_capture'][\$_capture_buffer]=ob_get_clean();\n";
$_output .= "} else \$_smarty_tpl->capture_error();?>";
return $_output;
@@ -23,6 +23,7 @@ class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('file');
/**
* Attribute definition: Overwrites base class.
*
@@ -30,30 +31,39 @@ class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('file', 'section');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('section', 'scope');
public $optional_attributes = array('section', 'scope', 'bubble_up');
/**
* Valid scope names
*
* @var array
*/
public $valid_scopes = array('local' => true, 'parent' => true, 'root' => true, 'global' => true,
'smarty' => true, 'tpl_root' => true);
/**
* Compiles code for the {config_load} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
static $_is_legal_scope = array('local' => true, 'parent' => true, 'root' => true, 'global' => true);
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
$compiler->trigger_template_error('nocache option not allowed', null, true);
}
// save possible attributes
@@ -63,19 +73,31 @@ class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase
} else {
$section = 'null';
}
$scope = 'local';
// scope setup
$_scope = Smarty::SCOPE_LOCAL;
if (isset($_attr['scope'])) {
$_attr['scope'] = trim($_attr['scope'], "'\"");
if (isset($_is_legal_scope[$_attr['scope']])) {
$scope = $_attr['scope'];
} else {
$compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno);
if (!isset($this->valid_scopes[$_attr['scope']])) {
$compiler->trigger_template_error("illegal value '{$_attr['scope']}' for \"scope\" attribute", null, true);
}
if ($_attr['scope'] != 'local') {
if ($_attr['scope'] == 'parent') {
$_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr['scope'] == 'root') {
$_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr['scope'] == 'global') {
$_scope = Smarty::SCOPE_GLOBAL;
} elseif ($_attr['scope'] == 'smarty') {
$_scope = Smarty::SCOPE_SMARTY;
} elseif ($_attr['scope'] == 'tpl_root') {
$_scope = Smarty::SCOPE_TPL_ROOT;
}
$_scope += (isset($_attr['bubble_up']) && $_attr['bubble_up'] == 'false') ? 0 : Smarty::SCOPE_BUBBLE_UP;
}
}
// create config object
$_output = "<?php \$_config = new Smarty_Internal_Config($conf_file, \$_smarty_tpl->smarty, \$_smarty_tpl);";
$_output .= "\$_config->loadConfigVars($section, '$scope'); ?>";
$_output =
"<?php\n\$_smarty_tpl->smarty->ext->configLoad->_loadConfigFile(\$_smarty_tpl, {$conf_file}, {$section}, {$_scope});\n?>\n";
return $_output;
}
@@ -23,6 +23,7 @@ class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('levels');
/**
* Attribute definition: Overwrites base class.
*
@@ -34,25 +35,26 @@ class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase
/**
* Compiles code for the {continue} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
$compiler->trigger_template_error('nocache option not allowed', null, true);
}
if (isset($_attr['levels'])) {
if (!is_numeric($_attr['levels'])) {
$compiler->trigger_template_error('level attribute must be a numeric constant', $compiler->lex->taglineno);
$compiler->trigger_template_error('level attribute must be a numeric constant', null, true);
}
$_levels = $_attr['levels'];
} else {
@@ -67,7 +69,7 @@ class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase
$stack_count --;
}
if ($level_count != 0) {
$compiler->trigger_template_error("cannot continue {$_levels} level(s)", $compiler->lex->taglineno);
$compiler->trigger_template_error("cannot continue {$_levels} level(s)", null, true);
}
return "<?php continue {$_levels};?>";
@@ -34,8 +34,8 @@ class Smarty_Internal_Compile_Debug extends Smarty_Internal_CompileBase
$compiler->tag_nocache = true;
// display debug template
$_output = "<?php \$_smarty_tpl->smarty->loadPlugin('Smarty_Internal_Debug'); Smarty_Internal_Debug::display_debug(\$_smarty_tpl); ?>";
$_output = "<?php \$_smarty_debug = new Smarty_Internal_Debug;\n \$_smarty_debug->display_debug(\$_smarty_tpl);\n";
$_output .= "unset(\$_smarty_debug);\n?>";
return $_output;
}
}
@@ -15,7 +15,7 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase
class Smarty_Internal_Compile_Extends extends Smarty_Internal_Compile_Shared_Inheritance
{
/**
* Attribute definition: Overwrites base class.
@@ -24,6 +24,15 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('file');
/**
* Array of names of optional attribute required by tag
* use array('_any') if there is no restriction of attributes names
*
* @var array
*/
public $optional_attributes = array('extends_resource');
/**
* Attribute definition: Overwrites base class.
*
@@ -33,53 +42,93 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase
public $shorttag_order = array('file');
/**
* Compiles code for the {extends} tag
* Compiles code for the {extends} tag extends: resource
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string compiled code
* @throws \SmartyCompilerException
* @throws \SmartyException
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
$compiler->trigger_template_error('nocache option not allowed', $compiler->parser->lex->line - 1);
}
if (strpos($_attr['file'], '$_tmp') !== false) {
$compiler->trigger_template_error('illegal value for file attribute', $compiler->lex->taglineno);
$compiler->trigger_template_error('illegal value for file attribute', $compiler->parser->lex->line - 1);
}
$name = $_attr['file'];
/** @var Smarty_Internal_Template $_smarty_tpl
* used in evaluated code
*/
$_smarty_tpl = $compiler->template;
eval("\$tpl_name = $name;");
// create template object
$_template = new $compiler->smarty->template_class($tpl_name, $compiler->smarty, $compiler->template);
// check for recursion
$uid = $_template->source->uid;
if (isset($compiler->extends_uid[$uid])) {
$compiler->trigger_template_error("illegal recursive call of \"$include_file\"", $compiler->lex->line - 1);
}
$compiler->extends_uid[$uid] = true;
if (empty($_template->source->components)) {
array_unshift($compiler->sources, $_template->source);
} else {
foreach ($_template->source->components as $source) {
array_unshift($compiler->sources, $source);
$uid = $source->uid;
if (isset($compiler->extends_uid[$uid])) {
$compiler->trigger_template_error("illegal recursive call of \"{$source->filepath}\"", $compiler->lex->line - 1);
// add code to initialize inheritance
$this->registerInit($compiler, true);
$file = trim($_attr['file'], '\'"');
if (strlen($file) > 8 && substr($file, 0, 8) == 'extends:') {
// generate code for each template
$files = array_reverse(explode('|', substr($file, 8)));
$i = 0;
foreach ($files as $file) {
if ($file[0] == '"') {
$file = trim($file, '".');
} else {
$file = "'{$file}'";
}
$compiler->extends_uid[$uid] = true;
$i ++;
if ($i == count($files) && isset($_attr['extends_resource'])) {
$this->compileEndChild($compiler);
}
$this->compileInclude($compiler, $file);
}
if (!isset($_attr['extends_resource'])) {
$this->compileEndChild($compiler);
}
} else {
$this->compileEndChild($compiler);
$this->compileInclude($compiler, $_attr['file']);
}
unset ($_template);
$compiler->inheritance_child = true;
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
$compiler->has_code = false;
return '';
}
/**
* Add code for inheritance endChild() method to end of template
*
* @param \Smarty_Internal_TemplateCompilerBase $compiler
*/
private function compileEndChild(Smarty_Internal_TemplateCompilerBase $compiler)
{
$compiler->parser->template_postfix[] = new Smarty_Internal_ParseTree_Tag($compiler->parser,
"<?php \$_smarty_tpl->ext->_inheritance->endChild(\$_smarty_tpl);\n?>\n");
}
/**
* Add code for including subtemplate to end of template
*
* @param \Smarty_Internal_TemplateCompilerBase $compiler
* @param string $file subtemplate name
*/
private function compileInclude(Smarty_Internal_TemplateCompilerBase $compiler, $file)
{
$compiler->parser->template_postfix[] = new Smarty_Internal_ParseTree_Tag($compiler->parser,
$compiler->compileTag('include',
array($file,
array('scope' => 'parent'))));
}
/**
* Create source code for {extends} from source components array
*
* @param []\Smarty_Internal_Template_Source $components
*
* @return string
*/
public static function extendsSourceArrayCode($components)
{
$resources = array();
foreach ($components as $source) {
$resources[] = $source->resource;
}
return '{extends file=\'extends:' . join('|', $resources) . '\' extends_resource=true}';
}
}
+43 -19
View File
@@ -34,6 +34,7 @@ class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase
*/
public function compile($args, $compiler, $parameter)
{
$compiler->loopNesting++;
if ($parameter == 0) {
$this->required_attributes = array('start', 'to');
$this->optional_attributes = array('max', 'step');
@@ -44,30 +45,51 @@ class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$output = "<?php ";
$output = "<?php\n";
if ($parameter == 1) {
foreach ($_attr['start'] as $_statement) {
$output .= " \$_smarty_tpl->tpl_vars[$_statement[var]] = new Smarty_Variable;";
$output .= " \$_smarty_tpl->tpl_vars[$_statement[var]]->value = $_statement[value];\n";
if (is_array($_statement['var'])) {
$var = $_statement['var']['var'];
$index = $_statement['var']['smarty_internal_index'];
} else {
$var = $_statement['var'];
$index = '';
}
$output .= "\$_smarty_tpl->tpl_vars[$var] = new Smarty_Variable;\n";
$output .= "\$_smarty_tpl->tpl_vars[$var]->value{$index} = {$_statement['value']};\n";
}
$output .= " if ($_attr[ifexp]) { for (\$_foo=true;$_attr[ifexp]; \$_smarty_tpl->tpl_vars[$_attr[var]]->value$_attr[step]) {\n";
if (is_array($_attr['var'])) {
$var = $_attr['var']['var'];
$index = $_attr['var']['smarty_internal_index'];
} else {
$var = $_attr['var'];
$index = '';
}
$output .= "if ($_attr[ifexp]) {\nfor (\$_foo=true;$_attr[ifexp]; \$_smarty_tpl->tpl_vars[$var]->value{$index}$_attr[step]) {\n";
} else {
$_statement = $_attr['start'];
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]] = new Smarty_Variable;";
if (isset($_attr['step'])) {
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->step = $_attr[step];";
if (is_array($_statement['var'])) {
$var = $_statement['var']['var'];
$index = $_statement['var']['smarty_internal_index'];
} else {
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->step = 1;";
$var = $_statement['var'];
$index = '';
}
$output .= "\$_smarty_tpl->tpl_vars[$var] = new Smarty_Variable;";
if (isset($_attr['step'])) {
$output .= "\$_smarty_tpl->tpl_vars[$var]->step = $_attr[step];";
} else {
$output .= "\$_smarty_tpl->tpl_vars[$var]->step = 1;";
}
if (isset($_attr['max'])) {
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->total = (int) min(ceil((\$_smarty_tpl->tpl_vars[$_statement[var]]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$_statement[var]]->step)),$_attr[max]);\n";
$output .= "\$_smarty_tpl->tpl_vars[$var]->total = (int) min(ceil((\$_smarty_tpl->tpl_vars[$var]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$var]->step)),$_attr[max]);\n";
} else {
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->total = (int) ceil((\$_smarty_tpl->tpl_vars[$_statement[var]]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$_statement[var]]->step));\n";
$output .= "\$_smarty_tpl->tpl_vars[$var]->total = (int) ceil((\$_smarty_tpl->tpl_vars[$var]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$var]->step));\n";
}
$output .= "if (\$_smarty_tpl->tpl_vars[$_statement[var]]->total > 0) {\n";
$output .= "for (\$_smarty_tpl->tpl_vars[$_statement[var]]->value = $_statement[value], \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration = 1;\$_smarty_tpl->tpl_vars[$_statement[var]]->iteration <= \$_smarty_tpl->tpl_vars[$_statement[var]]->total;\$_smarty_tpl->tpl_vars[$_statement[var]]->value += \$_smarty_tpl->tpl_vars[$_statement[var]]->step, \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration++) {\n";
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->first = \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration == 1;";
$output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->last = \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration == \$_smarty_tpl->tpl_vars[$_statement[var]]->total;";
$output .= "if (\$_smarty_tpl->tpl_vars[$var]->total > 0) {\n";
$output .= "for (\$_smarty_tpl->tpl_vars[$var]->value{$index} = $_statement[value], \$_smarty_tpl->tpl_vars[$var]->iteration = 1;\$_smarty_tpl->tpl_vars[$var]->iteration <= \$_smarty_tpl->tpl_vars[$var]->total;\$_smarty_tpl->tpl_vars[$var]->value{$index} += \$_smarty_tpl->tpl_vars[$var]->step, \$_smarty_tpl->tpl_vars[$var]->iteration++) {\n";
$output .= "\$_smarty_tpl->tpl_vars[$var]->first = \$_smarty_tpl->tpl_vars[$var]->iteration == 1;";
$output .= "\$_smarty_tpl->tpl_vars[$var]->last = \$_smarty_tpl->tpl_vars[$var]->iteration == \$_smarty_tpl->tpl_vars[$var]->total;";
}
$output .= "?>";
@@ -127,6 +149,7 @@ class Smarty_Internal_Compile_Forclose extends Smarty_Internal_CompileBase
*/
public function compile($args, $compiler, $parameter)
{
$compiler->loopNesting--;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// must endblock be nocache?
@@ -136,10 +159,11 @@ class Smarty_Internal_Compile_Forclose extends Smarty_Internal_CompileBase
list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('for', 'forelse'));
if ($openTag == 'forelse') {
return "<?php } ?>";
} else {
return "<?php }} ?>";
}
$output = "<?php }\n";
if ($openTag != 'forelse') {
$output .= "}\n";
}
$output .= "?>\n";
return $output;
}
}
@@ -14,7 +14,7 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Foreach extends Smarty_Internal_CompileBase
class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_ForeachSection
{
/**
* Attribute definition: Overwrites base class.
@@ -23,6 +23,7 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('from', 'item');
/**
* Attribute definition: Overwrites base class.
*
@@ -30,6 +31,7 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('name', 'key');
/**
* Attribute definition: Overwrites base class.
*
@@ -38,129 +40,229 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_CompileBase
*/
public $shorttag_order = array('from', 'item', 'key', 'name');
/**
* counter
*
* @var int
*/
public $counter = 0;
/**
* Name of this tag
*
* @var string
*/
public $tagName = 'foreach';
/**
* Valid properties of $smarty.foreach.name.xxx variable
*
* @var array
*/
public static $nameProperties = array('first', 'last', 'index', 'iteration', 'show', 'total');
/**
* Valid properties of $item@xxx variable
*
* @var array
*/
public $itemProperties = array('first', 'last', 'index', 'iteration', 'show', 'total', 'key');
/**
* Flag if tag had name attribute
*
* @var bool
*/
public $isNamed = false;
/**
* Compiles code for the {foreach} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
$compiler->loopNesting ++;
// init
$this->isNamed = false;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$from = $_attr['from'];
$item = $_attr['item'];
if (!strncmp("\$_smarty_tpl->tpl_vars[$item]", $from, strlen($item) + 24)) {
$compiler->trigger_template_error("item variable {$item} may not be the same variable as at 'from'", $compiler->lex->taglineno);
$item = $compiler->getId($_attr['item']);
if ($item === false) {
$item = $compiler->getVariableName($_attr['item']);
}
$attributes = array('item' => $item);
if (isset($_attr['key'])) {
$key = $_attr['key'];
} else {
$key = null;
$key = $compiler->getId($_attr['key']);
if ($key === false) {
$key = $compiler->getVariableName($_attr['key']);
}
$attributes['key'] = $key;
}
if (isset($_attr['name'])) {
$this->isNamed = true;
$attributes['name'] = $compiler->getId($_attr['name']);
}
foreach ($attributes as $a => $v) {
if ($v === false) {
$compiler->trigger_template_error("'{$a}' attribute/variable has illegal value", null, true);
}
}
$fromName = $compiler->getVariableName($_attr['from']);
if ($fromName) {
foreach (array('item', 'key') as $a) {
if (isset($attributes[$a]) && $attributes[$a] == $fromName) {
$compiler->trigger_template_error("'{$a}' and 'from' may not have same variable name '{$fromName}'",
null, true);
}
}
}
$this->openTag($compiler, 'foreach', array('foreach', $compiler->nocache, $item, $key));
$itemVar = "\$_smarty_tpl->tpl_vars['{$item}']";
$local = '$__foreach_' . (isset($attributes['name']) ? $attributes['name'] : $attributes['item']) . '_' .
$this->counter ++ . '_';
$needIteration = false;
// search for used tag attributes
$itemAttr = array();
$namedAttr = array();
$this->scanForProperties($attributes, $compiler);
if (!empty($this->matchResults['item'])) {
$itemAttr = $this->matchResults['item'];
}
if (!empty($this->matchResults['named'])) {
$namedAttr = $this->matchResults['named'];
}
if (isset($itemAttr['last'])) {
$needIteration = true;
}
if (isset($namedAttr['last'])) {
$needIteration = true;
}
$keyTerm = '';
if (isset($itemAttr['key'])) {
$keyTerm = "{$itemVar}->key => ";
} elseif (isset($attributes['key'])) {
$keyTerm = "\$_smarty_tpl->tpl_vars['{$key}']->value => ";
}
$saveVars = array();
$restoreVars = array();
if ($this->isNamed) {
$foreachVar = "\$_smarty_tpl->tpl_vars['__smarty_foreach_{$attributes['name']}']";
if (!empty($namedAttr)) {
$saveVars['saved'] = "isset({$foreachVar}) ? {$foreachVar} : false;";
$restoreVars[] = "if ({$local}saved) {\n{$foreachVar} = {$local}saved;\n}\n";
}
}
foreach (array('item', 'key') as $a) {
if (isset($attributes[$a])) {
$saveVars['saved_' . $a] =
"isset(\$_smarty_tpl->tpl_vars['{$attributes[$a]}']) ? \$_smarty_tpl->tpl_vars['{$attributes[$a]}'] : false;";
$restoreVars[] =
"if ({$local}saved_{$a}) {\n\$_smarty_tpl->tpl_vars['{$attributes[$a]}'] = {$local}saved_{$a};\n}\n";
}
}
$this->openTag($compiler, 'foreach',
array('foreach', $compiler->nocache, $local, $restoreVars, $itemVar, true));
// maybe nocache because of nocache variables
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
if (isset($_attr['name'])) {
$name = $_attr['name'];
$has_name = true;
$SmartyVarName = '$smarty.foreach.' . trim($name, '\'"') . '.';
} else {
$name = null;
$has_name = false;
}
$ItemVarName = '$' . trim($item, '\'"') . '@';
// evaluates which Smarty variables and properties have to be computed
if ($has_name) {
$usesSmartyFirst = strpos($compiler->lex->data, $SmartyVarName . 'first') !== false;
$usesSmartyLast = strpos($compiler->lex->data, $SmartyVarName . 'last') !== false;
$usesSmartyIndex = strpos($compiler->lex->data, $SmartyVarName . 'index') !== false;
$usesSmartyIteration = strpos($compiler->lex->data, $SmartyVarName . 'iteration') !== false;
$usesSmartyShow = strpos($compiler->lex->data, $SmartyVarName . 'show') !== false;
$usesSmartyTotal = strpos($compiler->lex->data, $SmartyVarName . 'total') !== false;
} else {
$usesSmartyFirst = false;
$usesSmartyLast = false;
$usesSmartyTotal = false;
$usesSmartyShow = false;
}
$usesPropFirst = $usesSmartyFirst || strpos($compiler->lex->data, $ItemVarName . 'first') !== false;
$usesPropLast = $usesSmartyLast || strpos($compiler->lex->data, $ItemVarName . 'last') !== false;
$usesPropIndex = $usesPropFirst || strpos($compiler->lex->data, $ItemVarName . 'index') !== false;
$usesPropIteration = $usesPropLast || strpos($compiler->lex->data, $ItemVarName . 'iteration') !== false;
$usesPropShow = strpos($compiler->lex->data, $ItemVarName . 'show') !== false;
$usesPropTotal = $usesSmartyTotal || $usesSmartyShow || $usesPropShow || $usesPropLast || strpos($compiler->lex->data, $ItemVarName . 'total') !== false;
// generate output code
$output = "<?php ";
$output .= " \$_smarty_tpl->tpl_vars[$item] = new Smarty_Variable; \$_smarty_tpl->tpl_vars[$item]->_loop = false;\n";
if ($key != null) {
$output .= " \$_smarty_tpl->tpl_vars[$key] = new Smarty_Variable;\n";
$output = "<?php\n";
$output .= "\$_from = $from;\n";
$output .= "if (!is_array(\$_from) && !is_object(\$_from)) {\n";
$output .= "settype(\$_from, 'array');\n";
$output .= "}\n";
foreach ($saveVars as $k => $code) {
$output .= "{$local}{$k} = {$code}\n";
}
$output .= " \$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array');}\n";
if ($usesPropTotal) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->total= \$_smarty_tpl->_count(\$_from);\n";
$output .= "{$itemVar} = new Smarty_Variable();\n";
$output .= "{$local}total = \$_smarty_tpl->smarty->ext->_foreach->count(\$_from);\n";
if (isset($itemAttr['show'])) {
$output .= "{$itemVar}->show = ({$local}total > 0);\n";
}
if ($usesPropIteration) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->iteration=0;\n";
if (isset($itemAttr['total'])) {
$output .= "{$itemVar}->total= {$local}total;\n";
}
if ($usesPropIndex) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->index=-1;\n";
}
if ($usesPropShow) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->show = (\$_smarty_tpl->tpl_vars[$item]->total > 0);\n";
}
if ($has_name) {
if ($usesSmartyTotal) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['total'] = \$_smarty_tpl->tpl_vars[$item]->total;\n";
if ($this->isNamed) {
$prop = array();
if (isset($namedAttr['total'])) {
$prop['total'] = "'total' => {$local}total";
}
if ($usesSmartyIteration) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']=0;\n";
if (isset($namedAttr['iteration'])) {
$prop['iteration'] = "'iteration' => 0";
}
if ($usesSmartyIndex) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']=-1;\n";
if (isset($namedAttr['index'])) {
$prop['index'] = "'index' => -1";
}
if ($usesSmartyShow) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['show']=(\$_smarty_tpl->tpl_vars[$item]->total > 0);\n";
if (isset($namedAttr['show'])) {
$prop['show'] = "'show' => ({$local}total > 0)";
}
if (!empty($namedAttr)) {
$_vars = 'array(' . join(', ', $prop) . ')';
$output .= "{$foreachVar} = new Smarty_Variable({$_vars});\n";
}
}
$output .= "foreach (\$_from as \$_smarty_tpl->tpl_vars[$item]->key => \$_smarty_tpl->tpl_vars[$item]->value) {\n\$_smarty_tpl->tpl_vars[$item]->_loop = true;\n";
if ($key != null) {
$output .= " \$_smarty_tpl->tpl_vars[$key]->value = \$_smarty_tpl->tpl_vars[$item]->key;\n";
$output .= "if ({$local}total) {\n";
if (isset($attributes['key'])) {
$output .= "\$_smarty_tpl->tpl_vars['{$key}'] = new Smarty_Variable();\n";
}
if ($usesPropIteration) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->iteration++;\n";
if (isset($namedAttr['first']) || isset($itemAttr['first'])) {
$output .= "{$local}first = true;\n";
}
if ($usesPropIndex) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->index++;\n";
if (isset($itemAttr['iteration'])) {
$output .= "{$itemVar}->iteration=0;\n";
}
if ($usesPropFirst) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->first = \$_smarty_tpl->tpl_vars[$item]->index === 0;\n";
if (isset($itemAttr['index'])) {
$output .= "{$itemVar}->index=-1;\n";
}
if ($usesPropLast) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->last = \$_smarty_tpl->tpl_vars[$item]->iteration === \$_smarty_tpl->tpl_vars[$item]->total;\n";
if ($needIteration) {
$output .= "{$local}iteration=0;\n";
}
if ($has_name) {
if ($usesSmartyFirst) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['first'] = \$_smarty_tpl->tpl_vars[$item]->first;\n";
$output .= "foreach (\$_from as {$keyTerm}{$itemVar}->value) {\n";
if (isset($attributes['key']) && isset($itemAttr['key'])) {
$output .= "\$_smarty_tpl->tpl_vars['{$key}']->value = {$itemVar}->key;\n";
}
if (isset($itemAttr['iteration'])) {
$output .= "{$itemVar}->iteration++;\n";
}
if (isset($itemAttr['index'])) {
$output .= "{$itemVar}->index++;\n";
}
if ($needIteration) {
$output .= "{$local}iteration++;\n";
}
if (isset($itemAttr['first'])) {
$output .= "{$itemVar}->first = {$local}first;\n";
}
if (isset($itemAttr['last'])) {
$output .= "{$itemVar}->last = {$local}iteration == {$local}total;\n";
}
if ($this->isNamed) {
if (isset($namedAttr['iteration'])) {
$output .= "{$foreachVar}->value['iteration']++;\n";
}
if ($usesSmartyIteration) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']++;\n";
if (isset($namedAttr['index'])) {
$output .= "{$foreachVar}->value['index']++;\n";
}
if ($usesSmartyIndex) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']++;\n";
if (isset($namedAttr['first'])) {
$output .= "{$foreachVar}->value['first'] = {$local}first;\n";
}
if ($usesSmartyLast) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['last'] = \$_smarty_tpl->tpl_vars[$item]->last;\n";
if (isset($namedAttr['last'])) {
$output .= "{$foreachVar}->value['last'] = {$local}iteration == {$local}total;\n";
}
}
if (isset($namedAttr['first']) || isset($itemAttr['first'])) {
$output .= "{$local}first = false;\n";
}
$output .= "{$local}saved_local_item = {$itemVar};\n";
$output .= "?>";
return $output;
@@ -178,21 +280,24 @@ class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase
/**
* Compiles code for the {foreachelse} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
list($openTag, $nocache, $item, $key) = $this->closeTag($compiler, array('foreach'));
$this->openTag($compiler, 'foreachelse', array('foreachelse', $nocache, $item, $key));
return "<?php }\nif (!\$_smarty_tpl->tpl_vars[$item]->_loop) {\n?>";
list($openTag, $nocache, $local, $restoreVars, $itemVar, $foo) = $this->closeTag($compiler, array('foreach'));
$this->openTag($compiler, 'foreachelse', array('foreachelse', $nocache, $local, $restoreVars, $itemVar, false));
$output = "<?php\n";
$output .= "{$itemVar} = {$local}saved_local_item;\n";
$output .= "}\n";
$output .= "} else {\n?>";
return $output;
}
}
@@ -207,23 +312,34 @@ class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase
/**
* Compiles code for the {/foreach} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$compiler->loopNesting --;
// must endblock be nocache?
if ($compiler->nocache) {
$compiler->tag_nocache = true;
}
list($openTag, $compiler->nocache, $item, $key) = $this->closeTag($compiler, array('foreach', 'foreachelse'));
list($openTag, $compiler->nocache, $local, $restoreVars, $itemVar, $restore) =
$this->closeTag($compiler, array('foreach', 'foreachelse'));
$output = "<?php\n";
return "<?php } ?>";
if ($restore) {
$output .= "{$itemVar} = {$local}saved_local_item;\n";
$output .= "}\n";
}
$output .= "}\n";
foreach ($restoreVars as $restore) {
$output .= $restore;
}
$output .= "?>";
return $output;
}
}
@@ -16,6 +16,7 @@
*/
class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@@ -23,6 +24,7 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('name');
/**
* Attribute definition: Overwrites base class.
*
@@ -30,6 +32,7 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name');
/**
* Attribute definition: Overwrites base class.
*
@@ -41,54 +44,31 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
/**
* Compiles code for the {function} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return boolean true
* @return bool true
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
$compiler->loopNesting++;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
$compiler->trigger_template_error('nocache option not allowed', null, true);
}
unset($_attr['nocache']);
$save = array($_attr, $compiler->parser->current_buffer,
$compiler->template->has_nocache_code, $compiler->template->required_plugins);
$this->openTag($compiler, 'function', $save);
$_name = trim($_attr['name'], "'\"");
unset($_attr['name']);
// set flag that we are compiling a template function
$compiler->compiles_template_function = true;
$compiler->template->properties['function'][$_name]['parameter'] = array();
/** @var Smarty_Internal_Template $_smarty_tpl
* used in evaluated code
*/
$_smarty_tpl = $compiler->template;
foreach ($_attr as $_key => $_data) {
eval ('$tmp=' . $_data . ';');
$compiler->template->properties['function'][$_name]['parameter'][$_key] = $tmp;
}
$compiler->smarty->template_functions[$_name]['parameter'] = $compiler->template->properties['function'][$_name]['parameter'];
if ($compiler->template->caching) {
$output = '';
} else {
$output = "<?php if (!function_exists('smarty_template_function_{$_name}')) {
function smarty_template_function_{$_name}(\$_smarty_tpl,\$params) {
\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
foreach (\$_smarty_tpl->smarty->template_functions['{$_name}']['parameter'] as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);};
foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
}
$compiler->parent_compiler->tpl_function[$_name] = $compiler->parent_compiler->template->tpl_function[$_name] = array();
$save = array($_attr, $compiler->parser->current_buffer, $compiler->template->compiled->has_nocache_code,
$compiler->template->caching);
$this->openTag($compiler, 'function', $save);
// Init temporary context
$compiler->template->required_plugins = array('compiled' => array(), 'nocache' => array());
$compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
$compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $output));
$compiler->template->has_nocache_code = false;
$compiler->has_code = false;
$compiler->template->properties['function'][$_name]['compiled'] = '';
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
$compiler->template->compiled->has_nocache_code = false;
return true;
}
}
@@ -101,62 +81,130 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
*/
class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
{
/**
* Compiler object
*
* @var object
*/
private $compiler = null;
/**
* Compiles code for the {/function} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param object|\Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return boolean true
* @return bool true
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
$_attr = $this->getAttributes($compiler, $args);
$compiler->loopNesting--;
$this->compiler = $compiler;
$saved_data = $this->closeTag($compiler, array('function'));
$_name = trim($saved_data[0]['name'], "'\"");
// build plugin include code
$plugins_string = '';
if (!empty($compiler->template->required_plugins['compiled'])) {
$plugins_string = '<?php ';
foreach ($compiler->template->required_plugins['compiled'] as $tmp) {
foreach ($tmp as $data) {
$plugins_string .= "if (!is_callable('{$data['function']}')) include '{$data['file']}';\n";
}
$_attr = $saved_data[0];
$_name = trim($_attr['name'], "'\"");
$compiler->parent_compiler->tpl_function[$_name]['called_functions'] = $compiler->parent_compiler->template->tpl_function[$_name]['called_functions'] = $compiler->called_functions;
$compiler->parent_compiler->tpl_function[$_name]['compiled_filepath'] = $compiler->parent_compiler->template->tpl_function[$_name]['compiled_filepath'] = $compiler->parent_compiler->template->compiled->filepath;
$compiler->parent_compiler->tpl_function[$_name]['uid'] = $compiler->parent_compiler->template->tpl_function[$_name]['uid'] = $compiler->template->source->uid;
$compiler->called_functions = array();
$_parameter = $_attr;
unset($_parameter['name']);
// default parameter
$_paramsArray = array();
foreach ($_parameter as $_key => $_value) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
$plugins_string .= '?>';
}
if (!empty($compiler->template->required_plugins['nocache'])) {
$plugins_string .= "<?php echo '/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php ";
foreach ($compiler->template->required_plugins['nocache'] as $tmp) {
foreach ($tmp as $data) {
$plugins_string .= "if (!is_callable(\'{$data['function']}\')) include \'{$data['file']}\';\n";
}
}
$plugins_string .= "?>/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/';?>\n";
}
// if caching save template function for possible nocache call
if ($compiler->template->caching) {
$compiler->template->properties['function'][$_name]['compiled'] .= $plugins_string
. $compiler->parser->current_buffer->to_smarty_php();
$compiler->template->properties['function'][$_name]['nocache_hash'] = $compiler->template->properties['nocache_hash'];
$compiler->template->properties['function'][$_name]['has_nocache_code'] = $compiler->template->has_nocache_code;
$compiler->template->properties['function'][$_name]['called_functions'] = $compiler->called_functions;
$compiler->called_functions = array();
$compiler->smarty->template_functions[$_name] = $compiler->template->properties['function'][$_name];
$compiler->has_code = false;
$output = true;
if (!empty($_paramsArray)) {
$_params = 'array(' . implode(",", $_paramsArray) . ')';
$_paramsCode = "\$params = array_merge($_params, \$params);\n";
} else {
$output = $plugins_string . $compiler->parser->current_buffer->to_smarty_php() . "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;
foreach (Smarty::\$global_tpl_vars as \$key => \$value) if(!isset(\$_smarty_tpl->tpl_vars[\$key])) \$_smarty_tpl->tpl_vars[\$key] = \$value;}}?>\n";
$_paramsCode = '';
}
// reset flag that we are compiling a template function
$compiler->compiles_template_function = false;
// restore old compiler status
$compiler->parser->current_buffer = $saved_data[1];
$compiler->template->has_nocache_code = $compiler->template->has_nocache_code | $saved_data[2];
$compiler->template->required_plugins = $saved_data[3];
$_functionCode = $compiler->parser->current_buffer;
// setup buffer for template function code
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
return $output;
$_funcName = "smarty_template_function_{$_name}_{$compiler->template->compiled->nocache_hash}";
$_funcNameCaching = $_funcName . '_nocache';
if ($compiler->template->compiled->has_nocache_code) {
$compiler->parent_compiler->tpl_function[$_name]['call_name_caching'] = $compiler->parent_compiler->template->tpl_function[$_name]['call_name_caching'] = $_funcNameCaching;
$output = "<?php\n";
$output .= "/* {$_funcNameCaching} */\n";
$output .= "if (!function_exists('{$_funcNameCaching}')) {\n";
$output .= "function {$_funcNameCaching} (\$_smarty_tpl,\$params) {\n";
$output .= "ob_start();\n";
$output .= "\$_smarty_tpl->compiled->has_nocache_code = true;\n";
$output .= $_paramsCode;
$output .= "\$_smarty_tpl->_cache['saved_tpl_vars'][] = \$_smarty_tpl->tpl_vars;\n";
$output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value);\n}";
$output .= "\$params = var_export(\$params, true);\n";
$output .= "echo \"/*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/<?php ";
$output .= "\\\$saved_tpl_vars = \\\$_smarty_tpl->tpl_vars;\nforeach (\$params as \\\$key => \\\$value) {\n\\\$_smarty_tpl->tpl_vars[\\\$key] = new Smarty_Variable(\\\$value);\n}\n?>";
$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n\";?>";
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $output));
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
$output = "<?php echo \"/*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/<?php ";
$output .= "foreach (Smarty::\\\$global_tpl_vars as \\\$key => \\\$value){\n";
$output .= "if (!isset(\\\$_smarty_tpl->tpl_vars[\\\$key]) || \\\$_smarty_tpl->tpl_vars[\\\$key] === \\\$value) \\\$saved_tpl_vars[\\\$key] = \\\$value;\n}\n";
$output .= "\\\$_smarty_tpl->tpl_vars = \\\$saved_tpl_vars;?>\n";
$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\";\n?>";
$output .= "<?php echo str_replace('{$compiler->template->compiled->nocache_hash}', \$_smarty_tpl->compiled->nocache_hash, ob_get_clean());\n";
$output .= "\$_smarty_tpl->tpl_vars = array_pop(\$_smarty_tpl->_cache['saved_tpl_vars']);\n}\n}\n";
$output .= "/*/ {$_funcName}_nocache */\n\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $output));
$_functionCode = new Smarty_Internal_ParseTree_Tag($compiler->parser, preg_replace_callback("/((<\?php )?echo '\/\*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/([\S\s]*?)\/\*\/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/", array($this,
'removeNocache'), $_functionCode->to_smarty_php($compiler->parser)));
}
$compiler->parent_compiler->tpl_function[$_name]['call_name'] = $compiler->parent_compiler->template->tpl_function[$_name]['call_name'] = $_funcName;
$output = "<?php\n";
$output .= "/* {$_funcName} */\n";
$output .= "if (!function_exists('{$_funcName}')) {\n";
$output .= "function {$_funcName}(\$_smarty_tpl,\$params) {\n";
$output .= "\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;\n";
$output .= $_paramsCode;
$output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value);\n}?>";
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $output));
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
$output = "<?php foreach (Smarty::\$global_tpl_vars as \$key => \$value){\n";
$output .= "if (!isset(\$_smarty_tpl->tpl_vars[\$key]) || \$_smarty_tpl->tpl_vars[\$key] === \$value) \$saved_tpl_vars[\$key] = \$value;\n}\n";
$output .= "\$_smarty_tpl->tpl_vars = \$saved_tpl_vars;\n}\n}\n";
$output .= "/*/ {$_funcName} */\n\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $output));
$compiler->parent_compiler->blockOrFunctionCode .= $compiler->parser->current_buffer->to_smarty_php($compiler->parser);
// nocache plugins must be copied
if (!empty($compiler->template->compiled->required_plugins['nocache'])) {
foreach ($compiler->template->compiled->required_plugins['nocache'] as $plugin => $tmp) {
foreach ($tmp as $type => $data) {
$compiler->parent_compiler->template->compiled->required_plugins['compiled'][$plugin][$type] = $data;
}
}
}
// restore old buffer
$compiler->parser->current_buffer = $saved_data[1];
// restore old status
$compiler->template->compiled->has_nocache_code = $saved_data[2];
$compiler->template->caching = $saved_data[3];
return true;
}
/**
* @param $match
*
* @return mixed
*/
function removeNocache($match)
{
$code = preg_replace("/((<\?php )?echo '\/\*%%SmartyNocache:{$this->compiler->template->compiled->nocache_hash}%%\*\/)|(\/\*\/%%SmartyNocache:{$this->compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/", '', $match[0]);
$code = str_replace(array('\\\'', '\\\\\''), array('\'', '\\\''), $code);
return $code;
}
}
+78 -36
View File
@@ -19,13 +19,14 @@ class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase
/**
* Compiles code for the {if} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
@@ -34,7 +35,7 @@ class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
if (!array_key_exists("if condition", $parameter)) {
$compiler->trigger_template_error("missing if condition", $compiler->lex->taglineno);
$compiler->trigger_template_error("missing if condition", null, true);
}
if (is_array($parameter['if condition'])) {
@@ -42,19 +43,32 @@ class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase
$_nocache = ',true';
// create nocache var to make it know for further compiling
if (is_array($parameter['if condition']['var'])) {
$compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true);
$var = trim($parameter['if condition']['var']['var'], "'");
} else {
$compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true);
$var = trim($parameter['if condition']['var'], "'");
}
if (isset($compiler->template->tpl_vars[$var])) {
$compiler->template->tpl_vars[$var]->nocache = true;
} else {
$compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
}
} else {
$_nocache = '';
}
if (is_array($parameter['if condition']['var'])) {
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . ") {?>";
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] .
"]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] .
"]->value)) \$_smarty_tpl->smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, " . $parameter['if condition']['var']['var'] .
"$_nocache);\n";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" .
$parameter['if condition']['var']['smarty_internal_index'] . " = " .
$parameter['if condition']['value'] . ") {?>";
} else {
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . ") {?>";
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] .
"])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] .
"] = new Smarty_Variable(null{$_nocache});";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " .
$parameter['if condition']['value'] . ") {?>";
}
return $_output;
@@ -75,13 +89,13 @@ class Smarty_Internal_Compile_Else extends Smarty_Internal_CompileBase
/**
* Compiles code for the {else} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif'));
$this->openTag($compiler, 'else', array($nesting, $compiler->tag_nocache));
@@ -101,13 +115,14 @@ class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase
/**
* Compiles code for the {elseif} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
@@ -115,7 +130,7 @@ class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase
list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif'));
if (!array_key_exists("if condition", $parameter)) {
$compiler->trigger_template_error("missing elseif condition", $compiler->lex->taglineno);
$compiler->trigger_template_error("missing elseif condition", null, true);
}
if (is_array($parameter['if condition'])) {
@@ -124,9 +139,14 @@ class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase
$_nocache = ',true';
// create nocache var to make it know for further compiling
if (is_array($parameter['if condition']['var'])) {
$compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true);
$var = trim($parameter['if condition']['var']['var'], "'");
} else {
$compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true);
$var = trim($parameter['if condition']['var'], "'");
}
if (isset($compiler->template->tpl_vars[$var])) {
$compiler->template->tpl_vars[$var]->nocache = true;
} else {
$compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
}
} else {
$_nocache = '';
@@ -139,11 +159,20 @@ class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase
if ($condition_by_assign) {
$this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
if (is_array($parameter['if condition']['var'])) {
$_output = "<?php } else { if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . ") {?>";
$_output = "<?php } else { if (!isset(\$_smarty_tpl->tpl_vars[" .
$parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" .
$parameter['if condition']['var']['var'] .
"]->value)) \$_smarty_tpl->smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, " .
$parameter['if condition']['var']['var'] . "$_nocache);\n";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" .
$parameter['if condition']['var']['smarty_internal_index'] . " = " .
$parameter['if condition']['value'] . ") {?>";
} else {
$_output = "<?php } else { if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . ") {?>";
$_output = "<?php } else { if (!isset(\$_smarty_tpl->tpl_vars[" .
$parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" .
$parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " .
$parameter['if condition']['value'] . ") {?>";
}
return $_output;
@@ -155,22 +184,35 @@ class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase
} else {
$tmp = '';
foreach ($compiler->prefix_code as $code) {
$tmp .= $code;
$tmp = $compiler->appendCode($tmp, $code);
}
$compiler->prefix_code = array();
$tmp = $compiler->appendCode("<?php } else {?>", $tmp);
$this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
if ($condition_by_assign) {
if (is_array($parameter['if condition']['var'])) {
$_output = "<?php } else {?>{$tmp}<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . ") {?>";
$_output = $compiler->appendCode($tmp, "<?php if (!isset(\$_smarty_tpl->tpl_vars[" .
$parameter['if condition']['var']['var'] .
"]) || !is_array(\$_smarty_tpl->tpl_vars[" .
$parameter['if condition']['var']['var'] .
"]->value)) \$_smarty_tpl->smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, " .
$parameter['if condition']['var']['var'] . "$_nocache);\n");
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" .
$parameter['if condition']['var']['smarty_internal_index'] . " = " .
$parameter['if condition']['value'] . ") {?>";
} else {
$_output = "<?php } else {?>{$tmp}<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . ") {?>";
$_output = $compiler->appendCode($tmp, "<?php if (!isset(\$_smarty_tpl->tpl_vars[" .
$parameter['if condition']['var'] .
"])) \$_smarty_tpl->tpl_vars[" .
$parameter['if condition']['var'] .
"] = new Smarty_Variable(null{$_nocache});");
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " .
$parameter['if condition']['value'] . ") {?>";
}
return $_output;
} else {
return "<?php } else {?>{$tmp}<?php if ({$parameter['if condition']}) {?>";
return $compiler->appendCode($tmp, "<?php if ({$parameter['if condition']}) {?>");
}
}
}
@@ -187,13 +229,13 @@ class Smarty_Internal_Compile_Ifclose extends Smarty_Internal_CompileBase
/**
* Compiles code for the {/if} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// must endblock be nocache?
if ($compiler->nocache) {
@@ -20,6 +20,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
* caching mode to create nocache code but no cache file
*/
const CACHING_NOCACHE_CODE = 9999;
/**
* Attribute definition: Overwrites base class.
*
@@ -27,6 +28,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('file');
/**
* Attribute definition: Overwrites base class.
*
@@ -34,13 +36,15 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('file');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $option_flags = array('nocache', 'inline', 'caching');
public $option_flags = array('nocache', 'inline', 'caching', 'bubble_up');
/**
* Attribute definition: Overwrites base class.
*
@@ -49,65 +53,161 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
*/
public $optional_attributes = array('_any');
/**
* Valid scope names
*
* @var array
*/
public $valid_scopes = array('local' => true, 'parent' => true, 'root' => true, 'global' => true,
'smarty' => true, 'tpl_root' => true);
/**
* Compiles code for the {include} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param Smarty_Internal_SmartyTemplateCompiler $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @throws SmartyCompilerException
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_SmartyTemplateCompiler $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// save possible attributes
$include_file = $_attr['file'];
$hashResourceName = $fullResourceName = $source_resource = $_attr['file'];
$variable_template = false;
$cache_tpl = false;
// parse resource_name
if (preg_match('/^([\'"])(([A-Za-z0-9_\-]{2,})[:])?(([^$()]+)|(.+))\1$/', $source_resource, $match)) {
$type = !empty($match[3]) ? $match[3] : $compiler->template->smarty->default_resource_type;
$name = !empty($match[5]) ? $match[5] : $match[6];
$handler = Smarty_Resource::load($compiler->smarty, $type);
if ($handler->recompiled || $handler->uncompiled) {
$variable_template = true;
}
if (!$variable_template) {
if ($type != 'string') {
$fullResourceName = "{$type}:{$name}";
$compiled = $compiler->parent_compiler->template->compiled;
if (isset($compiled->includes[$fullResourceName])) {
$compiled->includes[$fullResourceName] ++;
$cache_tpl = true;
} else {
$compiled->includes[$fullResourceName] = 1;
}
$fullResourceName = '"' . $fullResourceName . '"';
}
}
if (empty($match[5])) {
$variable_template = true;
}
} else {
$variable_template = true;
}
if (isset($_attr['assign'])) {
// output will be stored in a smarty variable instead of being displayed
$_assign = $_attr['assign'];
}
$_parent_scope = Smarty::SCOPE_LOCAL;
// scope setup
$_scope = Smarty::SCOPE_LOCAL;
if (isset($_attr['scope'])) {
$_attr['scope'] = trim($_attr['scope'], "'\"");
if ($_attr['scope'] == 'parent') {
$_parent_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr['scope'] == 'root') {
$_parent_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr['scope'] == 'global') {
$_parent_scope = Smarty::SCOPE_GLOBAL;
if (!isset($this->valid_scopes[$_attr['scope']])) {
$compiler->trigger_template_error("illegal value '{$_attr['scope']}' for \"scope\" attribute", null, true);
}
if ($_attr['scope'] != 'local') {
if ($_attr['scope'] == 'parent') {
$_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr['scope'] == 'root') {
$_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr['scope'] == 'global') {
$_scope = Smarty::SCOPE_GLOBAL;
} elseif ($_attr['scope'] == 'smarty') {
$_scope = Smarty::SCOPE_SMARTY;
} elseif ($_attr['scope'] == 'tpl_root') {
$_scope = Smarty::SCOPE_TPL_ROOT;
}
if ($_attr['bubble_up'] === true) {
$_scope = $_scope + Smarty::SCOPE_BUBBLE_UP;
}
}
}
// set flag to cache subtemplate object when called within loop or template name is variable.
if ($cache_tpl || $variable_template || $compiler->loopNesting > 0) {
$_cache_tpl = 'true';
} else {
$_cache_tpl = 'false';
}
// assume caching is off
$_caching = Smarty::CACHING_OFF;
// flag if included template code should be merged into caller
$merge_compiled_includes = ($compiler->smarty->merge_compiled_includes || ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes) || $_attr['inline'] === true) && !$compiler->template->source->recompiled;
if ($_attr['nocache'] === true) {
$compiler->tag_nocache = true;
}
// set default when in nocache mode
// if ($compiler->template->caching && ($compiler->nocache || $compiler->tag_nocache || $compiler->forceNocache == 2)) {
if ($compiler->template->caching && ((!$compiler->inheritance && !$compiler->nocache && !$compiler->tag_nocache) || ($compiler->inheritance && ($compiler->nocache || $compiler->tag_nocache)))) {
$call_nocache = $compiler->tag_nocache || $compiler->nocache;
// caching was on and {include} is not in nocache mode
if ($compiler->template->caching && !$compiler->nocache && !$compiler->tag_nocache) {
$_caching = self::CACHING_NOCACHE_CODE;
}
// flag if included template code should be merged into caller
$merge_compiled_includes = ($compiler->smarty->merge_compiled_includes || $_attr['inline'] === true) &&
!$compiler->template->source->handler->recompiled;
if ($merge_compiled_includes && $_attr['inline'] !== true) {
// variable template name ?
if ($variable_template) {
$merge_compiled_includes = false;
if ($compiler->template->caching) {
// must use individual cache file
//$_attr['caching'] = 1;
}
}
// variable compile_id?
if (isset($_attr['compile_id'])) {
if (!((substr_count($_attr['compile_id'], '"') == 2 || substr_count($_attr['compile_id'], "'") == 2 ||
is_numeric($_attr['compile_id']))) || substr_count($_attr['compile_id'], '(') != 0 ||
substr_count($_attr['compile_id'], '$_smarty_tpl->') != 0
) {
$merge_compiled_includes = false;
if ($compiler->template->caching) {
// must use individual cache file
//$_attr['caching'] = 1;
}
}
}
}
/*
* if the {include} tag provides individual parameter for caching
* it will not be included into the common cache file and treated like
* a nocache section
* if the {include} tag provides individual parameter for caching or compile_id
* the subtemplate must not be included into the common cache file and is treated like
* a call in nocache mode.
*
*/
if ($_attr['nocache'] !== true && $_attr['caching']) {
$_caching = $_new_caching = (int) $_attr['caching'];
$call_nocache = true;
} else {
$_new_caching = Smarty::CACHING_LIFETIME_CURRENT;
}
if (isset($_attr['cache_lifetime'])) {
$_cache_lifetime = $_attr['cache_lifetime'];
$compiler->tag_nocache = true;
$_caching = Smarty::CACHING_LIFETIME_CURRENT;
$call_nocache = true;
$_caching = $_new_caching;
} else {
$_cache_lifetime = 'null';
$_cache_lifetime = '$_smarty_tpl->cache_lifetime';
}
if (isset($_attr['cache_id'])) {
$_cache_id = $_attr['cache_id'];
$compiler->tag_nocache = true;
$_caching = Smarty::CACHING_LIFETIME_CURRENT;
$call_nocache = true;
$_caching = $_new_caching;
} else {
$_cache_id = '$_smarty_tpl->cache_id';
}
@@ -116,150 +216,151 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
} else {
$_compile_id = '$_smarty_tpl->compile_id';
}
if ($_attr['caching'] === true) {
$_caching = Smarty::CACHING_LIFETIME_CURRENT;
}
if ($_attr['nocache'] === true) {
$compiler->tag_nocache = true;
if ($merge_compiled_includes) {
$_caching = self::CACHING_NOCACHE_CODE;
} else {
$_caching = Smarty::CACHING_OFF;
}
// if subtemplate will be called in nocache mode do not merge
if ($compiler->template->caching && $call_nocache) {
$merge_compiled_includes = false;
}
$has_compiled_template = false;
if ($merge_compiled_includes && $_attr['inline'] !== true) {
// variable template name ?
if ($compiler->has_variable_string || !((substr_count($include_file, '"') == 2 || substr_count($include_file, "'") == 2))
|| substr_count($include_file, '(') != 0 || substr_count($include_file, '$_smarty_tpl->') != 0
) {
$merge_compiled_includes = false;
if ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes) {
$compiler->trigger_template_error(' variable template file names not allow within {block} tags');
}
}
// variable compile_id?
if (isset($_attr['compile_id'])) {
if (!((substr_count($_attr['compile_id'], '"') == 2 || substr_count($_attr['compile_id'], "'") == 2))
|| substr_count($_attr['compile_id'], '(') != 0 || substr_count($_attr['compile_id'], '$_smarty_tpl->') != 0
) {
$merge_compiled_includes = false;
if ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes) {
$compiler->trigger_template_error(' variable compile_id not allow within {block} tags');
}
}
}
}
if ($merge_compiled_includes) {
if ($compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache) && $_caching != self::CACHING_NOCACHE_CODE) {
$merge_compiled_includes = false;
if ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes) {
$compiler->trigger_template_error(' invalid caching mode of subtemplate within {block} tags');
}
}
}
if ($merge_compiled_includes) {
// we must observe different compile_id
$uid = sha1($_compile_id);
$tpl_name = null;
$nocache = false;
/** @var Smarty_Internal_Template $_smarty_tpl
* used in evaluated code
*/
$_smarty_tpl = $compiler->template;
eval("\$tpl_name = $include_file;");
if (!isset($compiler->smarty->merged_templates_func[$tpl_name][$uid])) {
$tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template, $compiler->template->cache_id, $compiler->template->compile_id);
// save unique function name
$compiler->smarty->merged_templates_func[$tpl_name][$uid]['func'] = $tpl->properties['unifunc'] = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
// use current nocache hash for inlined code
$compiler->smarty->merged_templates_func[$tpl_name][$uid]['nocache_hash'] = $tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
if ($compiler->template->caching && $_caching == self::CACHING_NOCACHE_CODE) {
// all code must be nocache
$nocache = true;
}
if ($compiler->inheritance) {
$tpl->compiler->inheritance = true;
}
// make sure whole chain gets compiled
$tpl->mustCompile = true;
if (!($tpl->source->uncompiled) && $tpl->source->exists) {
// get compiled code
$compiled_code = $tpl->compiler->compileTemplate($tpl, $nocache);
// release compiler object to free memory
unset($tpl->compiler);
// merge compiled code for {function} tags
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']);
// merge filedependency
$tpl->properties['file_dependency'][$tpl->source->uid] = array($tpl->source->filepath, $tpl->source->timestamp, $tpl->source->type);
$compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $tpl->properties['file_dependency']);
// remove header code
$compiled_code = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_code);
if ($tpl->has_nocache_code) {
// replace nocache_hash
$compiled_code = str_replace("{$tpl->properties['nocache_hash']}", $compiler->template->properties['nocache_hash'], $compiled_code);
$compiler->template->has_nocache_code = true;
}
$compiler->merged_templates[$tpl->properties['unifunc']] = $compiled_code;
$has_compiled_template = true;
unset ($tpl);
}
$c_id = isset($_attr['compile_id']) ? $_attr['compile_id'] : $compiler->template->compile_id;
// we must observe different compile_id and caching
$t_hash = sha1($c_id . ($_caching ? '--caching' : '--nocaching'));
if (!isset($compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash])) {
$has_compiled_template =
$this->compileInlineTemplate($compiler, $fullResourceName, $_caching, $hashResourceName, $t_hash,
$c_id);
} else {
$has_compiled_template = true;
}
}
// delete {include} standard attributes
unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']);
unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline'], $_attr['bubble_up']);
// remaining attributes must be assigned as smarty variable
$_vars_nc = '';
if (!empty($_attr)) {
if ($_parent_scope == Smarty::SCOPE_LOCAL) {
if ($_scope == Smarty::SCOPE_LOCAL) {
$_pairs = array();
// create variables
$nccode = '';
foreach ($_attr as $key => $value) {
$_pairs[] = "'$key'=>$value";
$nccode .= "\$_smarty_tpl->tpl_vars['$key'] = new Smarty_variable($value);\n";
$_vars_nc .= "\$_smarty_tpl->tpl_vars['$key'] = new Smarty_Variable($value);\n";
}
$_vars = 'array(' . join(',', $_pairs) . ')';
} else {
$compiler->trigger_template_error('variable passing not allowed in parent/global scope', $compiler->lex->taglineno);
$compiler->trigger_template_error('variable passing not allowed in parent/global scope', null, true);
}
} else {
$_vars = 'array()';
}
if ($has_compiled_template) {
// never call inline templates in nocache mode
$compiler->suppressNocacheProcessing = true;
$_hash = $compiler->smarty->merged_templates_func[$tpl_name][$uid]['nocache_hash'];
$_output = "<?php /* Call merged included template \"" . $tpl_name . "\" */\n";
$_output .= "\$_tpl_stack[] = \$_smarty_tpl;\n";
if (!empty($nccode) && $_caching == 9999 && $_smarty_tpl->caching) {
$compiler->suppressNocacheProcessing = false;
$_output .= substr($compiler->processNocacheCode('<?php ' .$nccode . "?>\n", true), 6, -3);
$compiler->suppressNocacheProcessing = true;
$update_compile_id = $compiler->template->caching && !$compiler->tag_nocache && !$compiler->nocache &&
$_compile_id != '$_smarty_tpl->compile_id';
if ($has_compiled_template && !$call_nocache) {
$_output = "<?php\n";
if ($update_compile_id) {
$_output .= $compiler->makeNocacheCode("\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n");
}
if (!empty($_vars_nc) && $_caching == 9999 && $compiler->template->caching) {
//$compiler->suppressNocacheProcessing = false;
$_output .= substr($compiler->processNocacheCode('<?php ' . $_vars_nc . "?>\n", true), 6, - 3);
//$compiler->suppressNocacheProcessing = true;
}
$_output .= " \$_smarty_tpl = \$_smarty_tpl->setupInlineSubTemplate($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, '$_hash');\n";
if (isset($_assign)) {
$_output .= 'ob_start(); ';
$_output .= "ob_start();\n";
}
$_output .= $compiler->smarty->merged_templates_func[$tpl_name][$uid]['func'] . "(\$_smarty_tpl);\n";
$_output .= "\$_smarty_tpl = array_pop(\$_tpl_stack); ";
$_output .= "\$_smarty_tpl->smarty->ext->_subtemplate->render(\$_smarty_tpl, {$fullResourceName}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_scope}, {$_cache_tpl}, '{$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['uid']}', '{$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func']}');\n";
if (isset($_assign)) {
$_output .= " \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(ob_get_clean());";
$_output .= "\$_smarty_tpl->assign({$_assign}, ob_get_clean());\n";
}
$_output .= "\n/* End of included template \"" . $tpl_name . "\" */?>";
if ($update_compile_id) {
$_output .= $compiler->makeNocacheCode("\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n");
}
$_output .= "?>\n";
return $_output;
}
if ($call_nocache) {
$compiler->tag_nocache = true;
}
$_output = "<?php ";
if ($update_compile_id) {
$_output .= "\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n";
}
// was there an assign attribute
if (isset($_assign)) {
$_output = "<?php \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(\$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope));?>\n";;
} else {
$_output = "<?php echo \$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope);?>\n";
$_output .= "ob_start();\n";
}
$_output .= "\$_smarty_tpl->smarty->ext->_subtemplate->render(\$_smarty_tpl, {$fullResourceName}, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_scope, {$_cache_tpl});\n";
if (isset($_assign)) {
$_output .= "\$_smarty_tpl->assign({$_assign}, ob_get_clean());\n";
}
if ($update_compile_id) {
$_output .= "\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n";
}
$_output .= "?>\n";
return $_output;
}
/**
* Compile inline sub template
*
* @param \Smarty_Internal_SmartyTemplateCompiler $compiler
* @param $fullResourceName
* @param $_caching
* @param $hashResourceName
* @param $t_hash
* @param $c_id
*
* @return bool
*/
public function compileInlineTemplate(Smarty_Internal_SmartyTemplateCompiler $compiler, $fullResourceName,
$_caching, $hashResourceName, $t_hash, $c_id)
{
$compiler->smarty->allow_ambiguous_resources = true;
/* @var Smarty_Internal_Template $tpl */
$tpl =
new $compiler->smarty->template_class (trim($fullResourceName, '"\''), $compiler->smarty, $compiler->template,
$compiler->template->cache_id, $c_id, $_caching);
if (!($tpl->source->handler->uncompiled) && $tpl->source->exists) {
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['uid'] = $tpl->source->uid;
if (isset($compiler->template->_inheritance)) {
$tpl->_inheritance = clone $compiler->template->_inheritance;
}
$tpl->compiled = new Smarty_Template_Compiled();
$tpl->compiled->nocache_hash = $compiler->parent_compiler->template->compiled->nocache_hash;
$tpl->loadCompiler();
// save unique function name
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func'] =
$tpl->compiled->unifunc = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
// make sure whole chain gets compiled
$tpl->mustCompile = true;
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['nocache_hash'] =
$tpl->compiled->nocache_hash;
// get compiled code
$compiled_code = "<?php\n\n";
$compiled_code .= "/* Start inline template \"{$tpl->source->type}:{$tpl->source->name}\" =============================*/\n";
$compiled_code .= "function {$tpl->compiled->unifunc} (\$_smarty_tpl) {\n";
$compiled_code .= "?>\n" . $tpl->compiler->compileTemplateSource($tpl, null, $compiler->parent_compiler);
$compiled_code .= "<?php\n";
$compiled_code .= "}\n?>\n";
$compiled_code .= $tpl->compiler->postFilter($tpl->compiler->blockOrFunctionCode);
$compiled_code .= "<?php\n\n";
$compiled_code .= "/* End inline template \"{$tpl->source->type}:{$tpl->source->name}\" =============================*/\n";
$compiled_code .= "?>";
unset($tpl->compiler);
if ($tpl->compiled->has_nocache_code) {
// replace nocache_hash
$compiled_code =
str_replace("{$tpl->compiled->nocache_hash}", $compiler->template->compiled->nocache_hash,
$compiled_code);
$compiler->template->compiled->has_nocache_code = true;
}
$compiler->parent_compiler->mergedSubTemplatesCode[$tpl->compiled->unifunc] = $compiled_code;
return true;
} else {
return false;
}
}
}
@@ -23,6 +23,7 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('file');
/**
* Attribute definition: Overwrites base class.
*
@@ -30,6 +31,7 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('file');
/**
* Attribute definition: Overwrites base class.
*
@@ -41,13 +43,14 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase
/**
* Compiles code for the {include_php} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @throws SmartyException
* @return string compiled code
* @return string
* @throws \SmartyCompilerException
* @throws \SmartyException
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
if (!($compiler->smarty instanceof SmartyBC)) {
throw new SmartyException("{include_php} is deprecated, use SmartyBC class to enable");
@@ -60,9 +63,10 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase
*/
$_smarty_tpl = $compiler->template;
$_filepath = false;
eval('$_file = ' . $_attr['file'] . ';');
$_file = null;
eval('$_file = @' . $_attr['file'] . ';');
if (!isset($compiler->smarty->security_policy) && file_exists($_file)) {
$_filepath = $_file;
$_filepath = $compiler->smarty->_realpath($_file, true);
} else {
if (isset($compiler->smarty->security_policy)) {
$_dir = $compiler->smarty->security_policy->trusted_dir;
@@ -71,16 +75,16 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase
}
if (!empty($_dir)) {
foreach ((array) $_dir as $_script_dir) {
$_script_dir = rtrim($_script_dir, '/\\') . DS;
if (file_exists($_script_dir . $_file)) {
$_filepath = $_script_dir . $_file;
$_path = $compiler->smarty->_realpath($_script_dir . DS . $_file, true);
if (file_exists($_path)) {
$_filepath = $_path;
break;
}
}
}
}
if ($_filepath == false) {
$compiler->trigger_template_error("{include_php} file '{$_file}' is not readable", $compiler->lex->taglineno);
$compiler->trigger_template_error("{include_php} file '{$_file}' is not readable", null, true);
}
if (isset($compiler->smarty->security_policy)) {
@@ -99,7 +103,7 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase
}
if (isset($_assign)) {
return "<?php ob_start(); include{$_once} ('{$_filepath}'); \$_smarty_tpl->assign({$_assign},ob_get_contents()); ob_end_clean();?>";
return "<?php ob_start();\ninclude{$_once} ('{$_filepath}');\n\$_smarty_tpl->assign({$_assign},ob_get_clean());\n?>";
} else {
return "<?php include{$_once} ('{$_filepath}');?>\n";
}
@@ -24,6 +24,7 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('name');
/**
* Attribute definition: Overwrites base class.
*
@@ -31,6 +32,7 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name');
/**
* Attribute definition: Overwrites base class.
*
@@ -42,17 +44,21 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase
/**
* Compiles code for the {insert} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// never compile as nocache code
$compiler->suppressNocacheProcessing = true;
$nocacheParam = $compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache);
if (!$nocacheParam) {
// do not compile as nocache code
$compiler->suppressNocacheProcessing = true;
}
$compiler->tag_nocache = true;
$_smarty_tpl = $compiler->template;
$_name = null;
@@ -60,19 +66,24 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase
$_output = '<?php ';
// save possible attributes
eval('$_name = ' . $_attr['name'] . ';');
eval('$_name = @' . $_attr['name'] . ';');
if (isset($_attr['assign'])) {
// output will be stored in a smarty variable instead of being displayed
$_assign = $_attr['assign'];
// create variable to make sure that the compiler knows about its nocache status
$compiler->template->tpl_vars[trim($_attr['assign'], "'")] = new Smarty_Variable(null, true);
$var = trim($_attr['assign'], "'");
if (isset($compiler->template->tpl_vars[$var])) {
$compiler->template->tpl_vars[$var]->nocache = true;
} else {
$compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
}
}
if (isset($_attr['script'])) {
// script which must be included
$_function = "smarty_insert_{$_name}";
$_smarty_tpl = $compiler->template;
$_filepath = false;
eval('$_script = ' . $_attr['script'] . ';');
eval('$_script = @' . $_attr['script'] . ';');
if (!isset($compiler->smarty->security_policy) && file_exists($_script)) {
$_filepath = $_script;
} else {
@@ -92,13 +103,13 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase
}
}
if ($_filepath == false) {
$compiler->trigger_template_error("{insert} missing script file '{$_script}'", $compiler->lex->taglineno);
$compiler->trigger_template_error("{insert} missing script file '{$_script}'", null, true);
}
// code for script file loading
$_output .= "require_once '{$_filepath}' ;";
require_once $_filepath;
if (!is_callable($_function)) {
$compiler->trigger_template_error(" {insert} function '{$_function}' is not callable in script file '{$_script}'", $compiler->lex->taglineno);
$compiler->trigger_template_error(" {insert} function '{$_function}' is not callable in script file '{$_script}'", null, true);
}
} else {
$_filepath = 'null';
@@ -107,7 +118,7 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase
if (!is_callable($_function)) {
// try plugin
if (!$_function = $compiler->getPlugin($_name, 'insert')) {
$compiler->trigger_template_error("{insert} no function or plugin found for '{$_name}'", $compiler->lex->taglineno);
$compiler->trigger_template_error("{insert} no function or plugin found for '{$_name}'", null, true);
}
}
}
@@ -121,14 +132,14 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase
$_params = 'array(' . implode(", ", $_paramsArray) . ')';
// call insert
if (isset($_assign)) {
if ($_smarty_tpl->caching) {
if ($_smarty_tpl->caching && !$nocacheParam) {
$_output .= "echo Smarty_Internal_Nocache_Insert::compile ('{$_function}',{$_params}, \$_smarty_tpl, '{$_filepath}',{$_assign});?>";
} else {
$_output .= "\$_smarty_tpl->assign({$_assign} , {$_function} ({$_params},\$_smarty_tpl), true);?>";
}
} else {
$compiler->has_output = true;
if ($_smarty_tpl->caching) {
if ($_smarty_tpl->caching && !$nocacheParam) {
$_output .= "echo Smarty_Internal_Nocache_Insert::compile ('{$_function}',{$_params}, \$_smarty_tpl, '{$_filepath}');?>";
} else {
$_output .= "echo {$_function}({$_params},\$_smarty_tpl);?>";
@@ -20,16 +20,17 @@ class Smarty_Internal_Compile_Ldelim extends Smarty_Internal_CompileBase
* Compiles code for the {ldelim} tag
* This tag does output the left delimiter
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
$compiler->trigger_template_error('nocache option not allowed', null, true);
}
// this tag does not return compiled code
$compiler->has_code = true;
@@ -16,21 +16,26 @@
*/
class Smarty_Internal_Compile_Nocache extends Smarty_Internal_CompileBase
{
/**
* Array of names of valid option flags
*
* @var array
*/
public $option_flags = array();
/**
* Compiles code for the {nocache} tag
* This tag does not generate compiled output. It only sets a compiler flag.
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return bool
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
}
$this->openTag($compiler, 'nocache', array($compiler->nocache));
// enter nocache mode
$compiler->nocache = true;
// this tag does not return compiled code
@@ -52,16 +57,16 @@ class Smarty_Internal_Compile_Nocacheclose extends Smarty_Internal_CompileBase
* Compiles code for the {/nocache} tag
* This tag does not generate compiled output. It only sets a compiler flag.
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return bool
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
$_attr = $this->getAttributes($compiler, $args);
// leave nocache mode
$compiler->nocache = false;
list($compiler->nocache) = $this->closeTag($compiler, array('nocache'));
// this tag does not return compiled code
$compiler->has_code = false;
@@ -27,15 +27,15 @@ class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_Compi
/**
* Compiles code for the execution of block plugin
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of block plugin
* @param string $function PHP function name
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of block plugin
* @param string $function PHP function name
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter, $tag, $function)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag, $function)
{
if (!isset($tag[5]) || substr($tag, - 5) != 'close') {
// opening tag of block plugin
@@ -60,7 +60,7 @@ class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_Compi
// maybe nocache because of nocache variables or nocache plugin
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
// compile code
$output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
} else {
// must endblock be nocache?
if ($compiler->nocache) {
@@ -75,9 +75,13 @@ class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_Compi
$mod_pre = $mod_post = '';
} else {
$mod_pre = ' ob_start(); ';
$mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'], 'value' => 'ob_get_clean()')) . ';';
$mod_post = 'echo ' .
$compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'],
'value' => 'ob_get_clean()')) . ';';
}
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre . " echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . " } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
" echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post .
" } array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
}
return $output . "\n";
@@ -0,0 +1,223 @@
<?php
/**
* Smarty Internal Plugin Compile ForeachSection
* Shared methods for {foreach} {section} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile ForeachSection Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_CompileBase
{
/**
* Preg search pattern
*
* @var string
*/
private $propertyPreg = '';
/**
* Offsets in preg match result
*
* @var array
*/
private $resultOffsets = array();
/**
* Start offset
*
* @var int
*/
private $startOffset = 0;
/**
* Name of this tag
*
* @var string
*/
public $tagName = '';
/**
* Valid properties of $smarty.xxx variable
*
* @var array
*/
public static $nameProperties = array();
/**
* {section} tag has no item properties
*
* @var array
*/
public $itemProperties = null;
/**
* {section} tag has always name attribute
*
* @var bool
*/
public $isNamed = true;
/**
* @var array
*/
public $matchResults = array();
/**
* Scan sources for used tag attributes
*
* @param array $attributes
* @param \Smarty_Internal_TemplateCompilerBase $compiler
*/
public function scanForProperties($attributes, Smarty_Internal_TemplateCompilerBase $compiler)
{
$this->propertyPreg = '~(';
$this->startOffset = 0;
$this->resultOffsets = array();
$this->matchResults = array('named' => array(), 'item' => array());
if ($this->isNamed) {
$this->buildPropertyPreg(true, $attributes);
}
if (isset($this->itemProperties)) {
if ($this->isNamed) {
$this->propertyPreg .= '|';
}
$this->buildPropertyPreg(false, $attributes);
}
$this->propertyPreg .= ')\W~i';
// Template source
$this->matchTemplateSource($compiler);
// Parent template source
$this->matchParentTemplateSource($compiler);
// {block} source
$this->matchBlockSource($compiler);
}
/**
* Build property preg string
*
* @param bool $named
* @param array $attributes
*/
public function buildPropertyPreg($named, $attributes)
{
if ($named) {
$this->resultOffsets['named'] = $this->startOffset + 3;
$this->propertyPreg .= "([\$]smarty[.]{$this->tagName}[.]{$attributes['name']}[.](";
$className = get_class($this);
$properties = $className::$nameProperties;
} else {
$this->resultOffsets['item'] = $this->startOffset + 3;
$this->propertyPreg .= "([\$]{$attributes['item']}[@](";
$properties = $this->itemProperties;
}
$this->startOffset += count($properties) + 2;
$propName = reset($properties);
while ($propName) {
$this->propertyPreg .= "({$propName})";
$propName = next($properties);
if ($propName) {
$this->propertyPreg .= '|';
}
}
$this->propertyPreg .= '))';
}
/**
* Find matches in source string
*
* @param string $source
*/
public function matchProperty($source)
{
preg_match_all($this->propertyPreg, $source, $match, PREG_SET_ORDER);
foreach ($this->resultOffsets as $key => $offset) {
foreach ($match as $m) {
if (isset($m[$offset]) && !empty($m[$offset])) {
$this->matchResults[$key][strtolower($m[$offset])] = true;
}
}
}
}
/**
* Find matches in template source
*
* @param \Smarty_Internal_TemplateCompilerBase $compiler
*/
public function matchTemplateSource(Smarty_Internal_TemplateCompilerBase $compiler)
{
$this->matchProperty($compiler->parser->lex->data);
}
/**
* Find matches in all parent template source
*
* @param \Smarty_Internal_TemplateCompilerBase $compiler
*/
public function matchParentTemplateSource(Smarty_Internal_TemplateCompilerBase $compiler)
{
// search parent compiler template source
$nextCompiler = $compiler;
while ($nextCompiler !== $nextCompiler->parent_compiler) {
$nextCompiler = $nextCompiler->parent_compiler;
if ($compiler !== $nextCompiler) {
// get template source
$_content = $nextCompiler->template->source->getContent();
if ($_content != '') {
// run pre filter if required
if ((isset($nextCompiler->smarty->autoload_filters['pre']) ||
isset($nextCompiler->smarty->registered_filters['pre']))) {
$_content = $nextCompiler->smarty->ext->_filter_Handler->runFilter('pre', $_content, $nextCompiler->template);
}
$this->matchProperty($_content);
}
}
}
}
/**
* Find matches in {block} tag source
*
* @param \Smarty_Internal_TemplateCompilerBase $compiler
*/
public function matchBlockSource(Smarty_Internal_TemplateCompilerBase $compiler)
{
}
/**
* Compiles code for the {$smarty.foreach.xxx} or {$smarty.section.xxx}tag
*
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public static function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
$tag = strtolower(trim($parameter[ 0 ], '"\''));
$name = isset($parameter[ 1 ]) ? $compiler->getId($parameter[ 1 ]) : false;
if (!$name) {
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", null, true);
}
/* @var Smarty_Internal_Compile_Foreach|Smarty_Internal_Compile_Section $className */
$className = 'Smarty_Internal_Compile_' . ucfirst($tag);
$property = isset($parameter[ 2 ]) ? strtolower($compiler->getId($parameter[ 2 ])) : false;
if (!$property || !in_array($property, $className::$nameProperties)) {
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} property attribute", null, true);
}
$tagVar = "'__smarty_{$tag}_{$name}'";
return "(isset(\$_smarty_tpl->tpl_vars[{$tagVar}]->value['{$property}']) ? \$_smarty_tpl->tpl_vars[{$tagVar}]->value['{$property}'] : null)";
}
}
@@ -23,6 +23,7 @@ class Smarty_Internal_Compile_Private_Function_Plugin extends Smarty_Internal_Co
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array();
/**
* Attribute definition: Overwrites base class.
*
@@ -34,15 +35,15 @@ class Smarty_Internal_Compile_Private_Function_Plugin extends Smarty_Internal_Co
/**
* Compiles code for the execution of function plugin
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of function plugin
* @param string $function PHP function name
* @param string $function PHP function name
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter, $tag, $function)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag, $function)
{
// This tag does create output
$compiler->has_output = true;
@@ -20,13 +20,14 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
/**
* Compiles code for modifier execution
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
@@ -52,7 +53,8 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
$output = "{$function}({$params})";
} else {
if (is_object($function[0])) {
$output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
$output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' .
$modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
} else {
$output = $function[0] . '::' . $function[1] . '(' . $params . ')';
}
@@ -73,7 +75,9 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
// modifiercompiler plugin
if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
if (!is_object($compiler->smarty->security_policy) ||
$compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)
) {
$plugin = 'smarty_modifiercompiler_' . $modifier;
$output = $plugin($single_modifier, $compiler);
}
@@ -85,7 +89,9 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
// modifier plugin
if ($function = $compiler->getPlugin($modifier, Smarty::PLUGIN_MODIFIER)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
if (!is_object($compiler->smarty->security_policy) ||
$compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)
) {
$output = "{$function}({$params})";
}
$compiler->known_modifier_type[$modifier] = $type;
@@ -96,7 +102,9 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
// PHP function
if (is_callable($modifier)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)) {
if (!is_object($compiler->smarty->security_policy) ||
$compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)
) {
$output = "{$modifier}({$params})";
}
$compiler->known_modifier_type[$modifier] = $type;
@@ -105,21 +113,29 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
break;
case 6:
// default plugin handler
if (isset($compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier]) || (is_callable($compiler->smarty->default_plugin_handler_func) && $compiler->getPluginFromDefaultHandler($modifier, Smarty::PLUGIN_MODIFIER))) {
if (isset($compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier]) ||
(is_callable($compiler->smarty->default_plugin_handler_func) &&
$compiler->getPluginFromDefaultHandler($modifier, Smarty::PLUGIN_MODIFIER))
) {
$function = $compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0];
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
if (!is_object($compiler->smarty->security_policy) ||
$compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)
) {
if (!is_array($function)) {
$output = "{$function}({$params})";
} else {
if (is_object($function[0])) {
$output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
$output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' .
$modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
} else {
$output = $function[0] . '::' . $function[1] . '(' . $params . ')';
}
}
}
if (isset($compiler->template->required_plugins['nocache'][$modifier][Smarty::PLUGIN_MODIFIER]['file']) || isset($compiler->template->required_plugins['compiled'][$modifier][Smarty::PLUGIN_MODIFIER]['file'])) {
if (isset($compiler->parent_compiler->template->compiled->required_plugins['nocache'][$modifier][Smarty::PLUGIN_MODIFIER]['file']) ||
isset($compiler->parent_compiler->template->compiled->required_plugins['compiled'][$modifier][Smarty::PLUGIN_MODIFIER]['file'])
) {
// was a plugin
$compiler->known_modifier_type[$modifier] = 4;
} else {
@@ -130,7 +146,7 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
}
}
if (!isset($compiler->known_modifier_type[$modifier])) {
$compiler->trigger_template_error("unknown modifier \"" . $modifier . "\"", $compiler->lex->taglineno);
$compiler->trigger_template_error("unknown modifier \"" . $modifier . "\"", null, true);
}
}
@@ -27,15 +27,15 @@ class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Inter
/**
* Compiles code for the execution of block plugin
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of block object
* @param string $method name of method to call
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of block object
* @param string $method name of method to call
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter, $tag, $method)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag, $method)
{
if (!isset($tag[5]) || substr($tag, - 5) != 'close') {
// opening tag of block plugin
@@ -60,7 +60,8 @@ class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Inter
// maybe nocache because of nocache variables or nocache plugin
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
// compile code
$output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}->{$method}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
$output =
"<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}->{$method}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
} else {
$base_tag = substr($tag, 0, - 5);
// must endblock be nocache?
@@ -76,9 +77,13 @@ class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Inter
$mod_pre = $mod_post = '';
} else {
$mod_pre = ' ob_start(); ';
$mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'], 'value' => 'ob_get_clean()')) . ';';
$mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(),
array('modifierlist' => $parameter['modifier_list'],
'value' => 'ob_get_clean()')) . ';';
}
$output = "<?php \$_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;" . $mod_pre . " echo \$_smarty_tpl->smarty->registered_objects['{$base_tag}'][0]->{$method}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . " } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
" echo \$_smarty_tpl->smarty->registered_objects['{$base_tag}'][0]->{$method}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " .
$mod_post . " } array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
}
return $output . "\n";
@@ -27,15 +27,15 @@ class Smarty_Internal_Compile_Private_Object_Function extends Smarty_Internal_Co
/**
* Compiles code for the execution of function plugin
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of function
* @param string $method name of method to call
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of function
* @param string $method name of method to call
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter, $tag, $method)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag, $method)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
@@ -0,0 +1,209 @@
<?php
/**
* Smarty Internal Plugin Compile PHP Expression
* Compiles any tag which will output an expression or variable
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile PHP Expression Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_Php extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('code', 'type');
/**
* Compiles code for generating output from any expression
*
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string
* @throws \SmartyException
*/
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$compiler->has_code = false;
if ($_attr['type'] == 'xml') {
$compiler->tag_nocache = true;
$save = $compiler->template->compiled->has_nocache_code;
$output = addcslashes($_attr['code'], "'\\");
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $compiler->processNocacheCode("<?php echo '" .
$output .
"';?>", $compiler, true)));
$compiler->template->compiled->has_nocache_code = $save;
return '';
}
if ($_attr['type'] != 'tag') {
if ($compiler->php_handling == Smarty::PHP_REMOVE) {
return '';
} elseif ($compiler->php_handling == Smarty::PHP_QUOTE) {
$output = preg_replace_callback('#(<\?(?:php|=)?)|(<%)|(<script\s+language\s*=\s*["\']?\s*php\s*["\']?\s*>)|(\?>)|(%>)|(<\/script>)#i', array($this,
'quote'), $_attr['code']);
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Text($output));
return '';
} elseif ($compiler->php_handling == Smarty::PHP_PASSTHRU || $_attr['type'] == 'unmatched') {
$compiler->tag_nocache = true;
$save = $compiler->template->compiled->has_nocache_code;
$output = addcslashes($_attr['code'], "'\\");
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $compiler->processNocacheCode("<?php echo '" .
$output .
"';?>", $compiler, true)));
$compiler->template->compiled->has_nocache_code = $save;
return '';
} elseif ($compiler->php_handling == Smarty::PHP_ALLOW) {
if (!($compiler->smarty instanceof SmartyBC)) {
$compiler->trigger_template_error('$smarty->php_handling PHP_ALLOW not allowed. Use SmartyBC to enable it', null, true);
}
$compiler->has_code = true;
return $_attr['code'];
} else {
$compiler->trigger_template_error('Illegal $smarty->php_handling value', null, true);
}
} else {
$compiler->has_code = true;
if (!($compiler->smarty instanceof SmartyBC)) {
$compiler->trigger_template_error('{php}{/php} tags not allowed. Use SmartyBC to enable them', null, true);
}
$ldel = preg_quote($compiler->smarty->left_delimiter, '#');
$rdel = preg_quote($compiler->smarty->right_delimiter, '#');
preg_match("#^({$ldel}php\\s*)((.)*?)({$rdel})#", $_attr['code'], $match);
if (!empty($match[2])) {
if ('nocache' == trim($match[2])) {
$compiler->tag_nocache = true;
} else {
$compiler->trigger_template_error("illegal value of option flag \"{$match[2]}\"", null, true);
}
}
return preg_replace(array("#^{$ldel}\\s*php\\s*(.)*?{$rdel}#",
"#{$ldel}\\s*/\\s*php\\s*{$rdel}$#"), array('<?php ', '?>'), $_attr['code']);
}
}
/**
* Lexer code for PHP tags
*
* This code has been moved from lexer here fo easier debugging and maintenance
*
* @param $lex
*/
public function parsePhp($lex)
{
$lex->token = Smarty_Internal_Templateparser::TP_PHP;
$close = 0;
$lex->taglineno = $lex->line;
$closeTag = '?>';
if (strpos($lex->value, '<?xml') === 0) {
$lex->is_xml = true;
$lex->token = Smarty_Internal_Templateparser::TP_NOCACHE;
return;
} elseif (strpos($lex->value, '<?') === 0) {
$lex->phpType = 'php';
} elseif (strpos($lex->value, '<%') === 0) {
$lex->phpType = 'asp';
$closeTag = '%>';
} elseif (strpos($lex->value, '%>') === 0) {
$lex->phpType = 'unmatched';
} elseif (strpos($lex->value, '?>') === 0) {
if ($lex->is_xml) {
$lex->is_xml = false;
$lex->token = Smarty_Internal_Templateparser::TP_NOCACHE;
return;
}
$lex->phpType = 'unmatched';
} elseif (strpos($lex->value, '<s') === 0) {
$lex->phpType = 'script';
$closeTag = '</script>';
} elseif (strpos($lex->value, $lex->smarty->left_delimiter) === 0) {
if ($lex->isAutoLiteral()) {
$lex->token = Smarty_Internal_Templateparser::TP_TEXT;
return;
}
$closeTag = "{$lex->smarty->left_delimiter}/php{$lex->smarty->right_delimiter}";
if ($lex->value == $closeTag) {
$lex->compiler->trigger_template_error("unexpected closing tag '{$closeTag}'");
}
$lex->phpType = 'tag';
}
if ($lex->phpType == 'unmatched') {
return;
}
if (($lex->phpType == 'php' || $lex->phpType == 'asp') &&
($lex->compiler->php_handling == Smarty::PHP_PASSTHRU || $lex->compiler->php_handling == Smarty::PHP_QUOTE)
) {
return;
}
$start = $lex->counter + strlen($lex->value);
$body = true;
if (preg_match('~' . preg_quote($closeTag, '~') . '~i', $lex->data, $match, PREG_OFFSET_CAPTURE, $start)) {
$close = $match[0][1];
} else {
$lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'");
}
while ($body) {
if (preg_match('~([/][*])|([/][/][^\n]*)|(\'[^\'\\\\]*(?:\\.[^\'\\\\]*)*\')|("[^"\\\\]*(?:\\.[^"\\\\]*)*")~', $lex->data, $match, PREG_OFFSET_CAPTURE, $start)) {
$value = $match[0][0];
$from = $pos = $match[0][1];
if ($pos > $close) {
$body = false;
} else {
$start = $pos + strlen($value);
$phpCommentStart = $value == '/*';
if ($phpCommentStart) {
$phpCommentEnd = preg_match('~([*][/])~', $lex->data, $match, PREG_OFFSET_CAPTURE, $start);
if ($phpCommentEnd) {
$pos2 = $match[0][1];
$start = $pos2 + strlen($match[0][0]);
}
}
while ($close > $pos && $close < $start) {
if (preg_match('~' . preg_quote($closeTag, '~') .
'~i', $lex->data, $match, PREG_OFFSET_CAPTURE, $from)) {
$close = $match[0][1];
$from = $close + strlen($match[0][0]);
} else {
$lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'");
}
}
if ($phpCommentStart && (!$phpCommentEnd || $pos2 > $close)) {
$lex->taglineno = $lex->line + substr_count(substr($lex->data, $lex->counter, $start), "\n");
$lex->compiler->trigger_template_error("missing PHP comment closing tag '*/'");
}
}
} else {
$body = false;
}
}
$lex->value = substr($lex->data, $lex->counter, $close + strlen($closeTag) - $lex->counter);
}
/*
* Call back function for $php_handling = PHP_QUOTE
*
*/
/**
* @param $match
*
* @return string
*/
private function quote($match)
{
return htmlspecialchars($match[0], ENT_QUOTES);
}
}
@@ -23,6 +23,7 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('assign');
/**
* Attribute definition: Overwrites base class.
*
@@ -34,14 +35,14 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
/**
* Compiles code for generating output from any expression
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @throws SmartyException
* @return string compiled code
* @return string
* @throws \SmartyException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
@@ -57,7 +58,8 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
$output = $parameter['value'];
// tag modifier
if (!empty($parameter['modifierlist'])) {
$output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifierlist'], 'value' => $output));
$output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifierlist'],
'value' => $output));
}
if (!$_attr['nofilter']) {
// default modifier
@@ -74,7 +76,8 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
}
$compiler->default_modifier_list = $modifierlist;
}
$output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $compiler->default_modifier_list, 'value' => $output));
$output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $compiler->default_modifier_list,
'value' => $output));
}
// autoescape html
if ($compiler->template->smarty->escape_html) {
@@ -82,7 +85,8 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
}
// loop over registered filters
if (!empty($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE])) {
foreach ($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE] as $key => $function) {
foreach ($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE] as $key =>
$function) {
if (!is_array($function)) {
$output = "{$function}({$output},\$_smarty_tpl)";
} elseif (is_object($function[0])) {
@@ -104,13 +108,14 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
}
}
}
if (isset($compiler->template->variable_filters)) {
foreach ($compiler->template->variable_filters as $filter) {
if (count($filter) == 1 && ($result = $this->compile_output_filter($compiler, $filter[0], $output)) !== false) {
$output = $result;
} else {
$output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => array($filter), 'value' => $output));
}
foreach ($compiler->variable_filters as $filter) {
if (count($filter) == 1 &&
($result = $this->compile_output_filter($compiler, $filter[0], $output)) !== false
) {
$output = $result;
} else {
$output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => array($filter),
'value' => $output));
}
}
}
@@ -123,23 +128,23 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
}
/**
* @param object $compiler compiler object
* @param string $name name of variable filter
* @param string $output embedded output
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param string $name name of variable filter
* @param string $output embedded output
*
* @return string
*/
private function compile_output_filter($compiler, $name, $output)
private function compile_output_filter(Smarty_Internal_TemplateCompilerBase $compiler, $name, $output)
{
$plugin_name = "smarty_variablefilter_{$name}";
$path = $compiler->smarty->loadPlugin($plugin_name, false);
if ($path) {
if ($compiler->template->caching) {
$compiler->template->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['file'] = $path;
$compiler->template->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name;
$compiler->parent_compiler->template->compiled->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['file'] = $path;
$compiler->parent_compiler->template->compiled->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name;
} else {
$compiler->template->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['file'] = $path;
$compiler->template->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name;
$compiler->parent_compiler->template->compiled->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['file'] = $path;
$compiler->parent_compiler->template->compiled->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name;
}
} else {
// not found
@@ -27,14 +27,14 @@ class Smarty_Internal_Compile_Private_Registered_Block extends Smarty_Internal_C
/**
* Compiles code for the execution of a block function
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of block function
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of block function
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter, $tag)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag)
{
if (!isset($tag[5]) || substr($tag, - 5) != 'close') {
// opening tag of block plugin
@@ -69,11 +69,11 @@ class Smarty_Internal_Compile_Private_Registered_Block extends Smarty_Internal_C
$function = $tag_info[0];
// compile code
if (!is_array($function)) {
$output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
} elseif (is_object($function[0])) {
$output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_plugins['block']['{$tag}'][0][0]->{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_plugins['block']['{$tag}'][0][0]->{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
} else {
$output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function[0]}::{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
$output = "<?php \$_smarty_tpl->smarty->_cache['tag_stack'][] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function[0]}::{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
}
} else {
// must endblock be nocache?
@@ -95,14 +95,22 @@ class Smarty_Internal_Compile_Private_Registered_Block extends Smarty_Internal_C
$mod_pre = $mod_post = '';
} else {
$mod_pre = ' ob_start(); ';
$mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'], 'value' => 'ob_get_clean()')) . ';';
$mod_post = 'echo ' .
$compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'],
'value' => 'ob_get_clean()')) . ';';
}
if (!is_array($function)) {
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre . " echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat);" . $mod_post . " } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
" echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat);" . $mod_post .
" } array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
} elseif (is_object($function[0])) {
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre . " echo \$_smarty_tpl->smarty->registered_plugins['block']['{$base_tag}'][0][0]->{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . "} array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
" echo \$_smarty_tpl->smarty->registered_plugins['block']['{$base_tag}'][0][0]->{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " .
$mod_post . "} array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
} else {
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre . " echo {$function[0]}::{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . "} array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
$output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;" . $mod_pre .
" echo {$function[0]}::{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " .
$mod_post . "} array_pop(\$_smarty_tpl->smarty->_cache['tag_stack']);?>";
}
}
@@ -27,14 +27,14 @@ class Smarty_Internal_Compile_Private_Registered_Function extends Smarty_Interna
/**
* Compiles code for the execution of a registered function
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of function
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
* @param string $tag name of function
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter, $tag)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter, $tag)
{
// This tag does create output
$compiler->has_output = true;
@@ -19,96 +19,111 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
/**
* Compiles code for the special $smarty variables
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param $parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param $parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
$_index = preg_split("/\]\[/", substr($parameter, 1, strlen($parameter) - 2));
$compiled_ref = ' ';
$variable = trim($_index[0], "'");
switch ($variable) {
case 'foreach':
return "\$_smarty_tpl->getVariable('smarty')->value$parameter";
case 'section':
return "\$_smarty_tpl->getVariable('smarty')->value$parameter";
case 'capture':
return "Smarty::\$_smarty_vars$parameter";
case 'now':
return 'time()';
case 'cookies':
if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_super_globals) {
$compiler->trigger_template_error("(secure mode) super globals not permitted");
break;
}
$compiled_ref = '$_COOKIE';
break;
case 'get':
case 'post':
case 'env':
case 'server':
case 'session':
case 'request':
if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_super_globals) {
$compiler->trigger_template_error("(secure mode) super globals not permitted");
break;
}
$compiled_ref = '$_' . strtoupper($variable);
break;
case 'template':
return 'basename($_smarty_tpl->source->filepath)';
case 'template_object':
return '$_smarty_tpl';
case 'current_dir':
return 'dirname($_smarty_tpl->source->filepath)';
case 'version':
$_version = Smarty::SMARTY_VERSION;
return "'$_version'";
case 'const':
if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_constants) {
$compiler->trigger_template_error("(secure mode) constants not permitted");
break;
}
return "@constant({$_index[1]})";
case 'config':
if (isset($_index[2])) {
return "(is_array(\$tmp = \$_smarty_tpl->getConfigVariable($_index[1])) ? \$tmp[$_index[2]] : null)";
} else {
return "\$_smarty_tpl->getConfigVariable($_index[1])";
}
case 'ldelim':
$_ldelim = $compiler->smarty->left_delimiter;
return "'$_ldelim'";
case 'rdelim':
$_rdelim = $compiler->smarty->right_delimiter;
return "'$_rdelim'";
default:
$compiler->trigger_template_error('$smarty.' . trim($_index[0], "'") . ' is invalid');
break;
$variable = strtolower($compiler->getId($_index[0]));
if ($variable === false) {
$compiler->trigger_template_error("special \$Smarty variable name index can not be variable", null, true);
}
if (isset($_index[1])) {
array_shift($_index);
foreach ($_index as $_ind) {
$compiled_ref = $compiled_ref . "[$_ind]";
if (!isset($compiler->smarty->security_policy) ||
$compiler->smarty->security_policy->isTrustedSpecialSmartyVar($variable, $compiler)
) {
switch ($variable) {
case 'foreach':
case 'section':
return Smarty_Internal_Compile_Private_ForeachSection::compileSpecialVariable(array(), $compiler, $_index);
case 'capture':
if (class_exists('Smarty_Internal_Compile_Capture')) {
return Smarty_Internal_Compile_Capture::compileSpecialVariable(array(), $compiler, $_index);
}
return '';
case 'now':
return 'time()';
case 'cookies':
if (isset($compiler->smarty->security_policy) &&
!$compiler->smarty->security_policy->allow_super_globals
) {
$compiler->trigger_template_error("(secure mode) super globals not permitted");
break;
}
return '$_COOKIE';
case 'get':
case 'post':
case 'env':
case 'server':
case 'session':
case 'request':
if (isset($compiler->smarty->security_policy) &&
!$compiler->smarty->security_policy->allow_super_globals
) {
$compiler->trigger_template_error("(secure mode) super globals not permitted");
break;
}
$compiled_ref = '$_' . strtoupper($variable);
break;
case 'template':
return 'basename($_smarty_tpl->source->filepath)';
case 'template_object':
return '$_smarty_tpl';
case 'current_dir':
return 'dirname($_smarty_tpl->source->filepath)';
case 'version':
$_version = Smarty::SMARTY_VERSION;
return "'$_version'";
case 'const':
if (isset($compiler->smarty->security_policy) &&
!$compiler->smarty->security_policy->allow_constants
) {
$compiler->trigger_template_error("(secure mode) constants not permitted");
break;
}
if (strpos($_index[1], '$') === false && strpos($_index[1], '\'') === false) {
return "@constant('{$_index[1]}')";
} else {
return "@constant({$_index[1]})";
}
case 'config':
if (isset($_index[2])) {
return "(is_array(\$tmp = \$_smarty_tpl->smarty->ext->_config->_getConfigVariable(\$_smarty_tpl, $_index[1])) ? \$tmp[$_index[2]] : null)";
} else {
return "\$_smarty_tpl->smarty->ext->_config->_getConfigVariable(\$_smarty_tpl, $_index[1])";
}
case 'ldelim':
$_ldelim = $compiler->smarty->left_delimiter;
return "'$_ldelim'";
case 'rdelim':
$_rdelim = $compiler->smarty->right_delimiter;
return "'$_rdelim'";
default:
$compiler->trigger_template_error('$smarty.' . trim($_index[0], "'") . ' is invalid');
break;
}
if (isset($_index[1])) {
array_shift($_index);
foreach ($_index as $_ind) {
$compiled_ref = $compiled_ref . "[$_ind]";
}
}
return $compiled_ref;
}
return $compiled_ref;
}
}
@@ -25,11 +25,11 @@ class Smarty_Internal_Compile_Rdelim extends Smarty_Internal_CompileBase
*
* @return string compiled code
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
$compiler->trigger_template_error('nocache option not allowed', null, true);
}
// this tag does not return compiled code
$compiler->has_code = true;
@@ -14,7 +14,7 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Section extends Smarty_Internal_CompileBase
class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_ForeachSection
{
/**
* Attribute definition: Overwrites base class.
@@ -23,6 +23,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('name', 'loop');
/**
* Attribute definition: Overwrites base class.
*
@@ -30,6 +31,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_CompileBase
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name', 'loop');
/**
* Attribute definition: Overwrites base class.
*
@@ -38,103 +40,343 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_CompileBase
*/
public $optional_attributes = array('start', 'step', 'max', 'show');
/**
* counter
*
* @var int
*/
public $counter = 0;
/**
* Name of this tag
*
* @var string
*/
public $tagName = 'section';
/**
* Valid properties of $smarty.section.name.xxx variable
*
* @var array
*/
public static $nameProperties = array('first', 'last', 'index', 'iteration', 'show', 'total', 'rownum',
'index_prev', 'index_next');
/**
* {section} tag has no item properties
*
* @var array
*/
public $itemProperties = null;
/**
* {section} tag has always name attribute
*
* @var bool
*/
public $isNamed = true;
/**
* Compiles code for the {section} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
$compiler->loopNesting++;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$this->openTag($compiler, 'section', array('section', $compiler->nocache));
$attributes = array('name' => $compiler->getId($_attr['name']));
unset($_attr['name']);
foreach ($attributes as $a => $v) {
if ($v === false) {
$compiler->trigger_template_error("'{$a}' attribute/variable has illegal value", null, true);
}
}
$local = "\$__section_{$attributes['name']}_" . $this->counter ++ . '_';
$sectionVar = "\$_smarty_tpl->tpl_vars['__smarty_section_{$attributes['name']}']";
$this->openTag($compiler, 'section', array('section', $compiler->nocache, $local, $sectionVar));
// maybe nocache because of nocache variables
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
$output = "<?php ";
$section_name = $_attr['name'];
$output .= "if (isset(\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name])) unset(\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name]);\n";
$section_props = "\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name]";
$initLocal = array('saved' => "isset(\$_smarty_tpl->tpl_vars['__smarty_section_{$attributes['name']}']) ? \$_smarty_tpl->tpl_vars['__section_{$attributes['name']}'] : false",);
$initNamedProperty = array();
$initFor = array();
$incFor = array();
$cmpFor = array();
$propValue = array('index' => "{$sectionVar}->value['index']", 'show' => 'true', 'step' => 1,
'iteration' => "{$local}iteration",
);
$propType = array('index' => 2, 'iteration' => 2, 'show' => 0, 'step' => 0,);
// search for used tag attributes
$this->scanForProperties($attributes, $compiler);
if (!empty($this->matchResults['named'])) {
$namedAttr = $this->matchResults['named'];
}
$namedAttr['index'] = true;
$output = "<?php\n";
foreach ($_attr as $attr_name => $attr_value) {
switch ($attr_name) {
case 'loop':
$output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int) \$_loop); unset(\$_loop);\n";
if (is_numeric($attr_value)) {
$v = (int) $attr_value;
$t = 0;
} else {
$v = "(is_array(@\$_loop=$attr_value) ? count(\$_loop) : max(0, (int) \$_loop))";
$t = 1;
}
if (isset($namedAttr['loop'])) {
$initNamedProperty['loop'] = "'loop' => {$v}";
if ($t == 1) {
$v = "{$sectionVar}->value['loop']";
}
} elseif ($t == 1) {
$initLocal['loop'] = $v;
$v = "{$local}loop";
}
break;
case 'show':
if (is_bool($attr_value)) {
$show_attr_value = $attr_value ? 'true' : 'false';
$v = $attr_value ? 'true' : 'false';
$t = 0;
} else {
$show_attr_value = "(bool) $attr_value";
$v = "(bool) $attr_value";
$t = 3;
}
$output .= "{$section_props}['show'] = $show_attr_value;\n";
break;
case 'name':
$output .= "{$section_props}['$attr_name'] = $attr_value;\n";
case 'step':
if (is_numeric($attr_value)) {
$v = (int) $attr_value;
$v = ($v == 0) ? 1 : $v;
$t = 0;
break;
}
$initLocal['step'] = "((int)@$attr_value) == 0 ? 1 : (int)@$attr_value";
$v = "{$local}step";
$t = 2;
break;
case 'max':
case 'start':
$output .= "{$section_props}['$attr_name'] = (int) $attr_value;\n";
if (is_numeric($attr_value)) {
$v = (int) $attr_value;
$t = 0;
break;
}
$v = "(int)@$attr_value";
$t = 3;
break;
}
if ($t == 3 && $compiler->getId($attr_value)) {
$t = 1;
}
$propValue[$attr_name] = $v;
$propType[$attr_name] = $t;
}
case 'step':
$output .= "{$section_props}['$attr_name'] = ((int) $attr_value) == 0 ? 1 : (int) $attr_value;\n";
break;
if (isset($namedAttr['step'])) {
$initNamedProperty['step'] = $propValue['step'];
}
if (isset($namedAttr['iteration'])) {
$propValue['iteration'] = "{$sectionVar}->value['iteration']";
}
$incFor['iteration'] = "{$propValue['iteration']}++";
$initFor['iteration'] = "{$propValue['iteration']} = 1";
if ($propType['step'] == 0) {
if ($propValue['step'] == 1) {
$incFor['index'] = "{$sectionVar}->value['index']++";
} elseif ($propValue['step'] > 1) {
$incFor['index'] = "{$sectionVar}->value['index'] += {$propValue['step']}";
} else {
$incFor['index'] = "{$sectionVar}->value['index'] -= " . - $propValue['step'];
}
} else {
$incFor['index'] = "{$sectionVar}->value['index'] += {$propValue['step']}";
}
if (!isset($propValue['max'])) {
$propValue['max'] = $propValue['loop'];
$propType['max'] = $propType['loop'];
} elseif ($propType['max'] != 0) {
$propValue['max'] = "{$propValue['max']} < 0 ? {$propValue['loop']} : {$propValue['max']}";
$propType['max'] = 1;
} else {
if ($propValue['max'] < 0) {
$propValue['max'] = $propValue['loop'];
$propType['max'] = $propType['loop'];
}
}
if (!isset($_attr['show'])) {
$output .= "{$section_props}['show'] = true;\n";
}
if (!isset($_attr['loop'])) {
$output .= "{$section_props}['loop'] = 1;\n";
}
if (!isset($_attr['max'])) {
$output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
if (!isset($propValue['start'])) {
$start_code = array(1 => "{$propValue['step']} > 0 ? ", 2 => '0', 3 => ' : ', 4 => $propValue['loop'],
5 => ' - 1');
if ($propType['loop'] == 0) {
$start_code[5] = '';
$start_code[4] = $propValue['loop'] - 1;
}
if ($propType['step'] == 0) {
if ($propValue['step'] > 0) {
$start_code = array(1 => '0');
$propType['start'] = 0;
} else {
$start_code[1] = $start_code[2] = $start_code[3] = '';
$propType['start'] = $propType['loop'];
}
} else {
$propType['start'] = 1;
}
$propValue['start'] = join('', $start_code);
} else {
$output .= "if ({$section_props}['max'] < 0)\n" . " {$section_props}['max'] = {$section_props}['loop'];\n";
$start_code = array(1 => "{$propValue['start']} < 0 ? ", 2 => 'max(', 3 => "{$propValue['step']} > 0 ? ",
4 => '0', 5 => ' : ', 6 => '-1', 7 => ', ',
8 => "{$propValue['start']} + {$propValue['loop']}", 10 => ')', 11 => ' : ',
12 => 'min(', 13 => $propValue['start'], 14 => ', ',
15 => "{$propValue['step']} > 0 ? ", 16 => $propValue['loop'], 17 => ' : ',
18 => $propType['loop'] == 0 ? $propValue['loop'] - 1 : "{$propValue['loop']} - 1",
19 => ')');
if ($propType['step'] == 0) {
$start_code[3] = $start_code[5] = $start_code[15] = $start_code[17] = '';
if ($propValue['step'] > 0) {
$start_code[6] = $start_code[18] = '';
} else {
$start_code[4] = $start_code[16] = '';
}
}
if ($propType['start'] == 0) {
if ($propType['loop'] == 0) {
$start_code[8] = $propValue['start'] + $propValue['loop'];
}
$propType['start'] = $propType['step'] + $propType['loop'];
$start_code[1] = '';
if ($propValue['start'] < 0) {
for ($i = 11; $i <= 19; $i ++) {
$start_code[$i] = '';
}
if ($propType['start'] == 0) {
$start_code = array(max($propValue['step'] > 0 ? 0 : - 1, $propValue['start'] +
$propValue['loop']));
}
} else {
for ($i = 1; $i <= 11; $i ++) {
$start_code[$i] = '';
}
if ($propType['start'] == 0) {
$start_code = array(min($propValue['step'] > 0 ? $propValue['loop'] : $propValue['loop'] -
1, $propValue['start']));
}
}
}
$propValue['start'] = join('', $start_code);
}
if ($propType['start'] != 0) {
$initLocal['start'] = $propValue['start'];
$propValue['start'] = "{$local}start";
}
if (!isset($_attr['step'])) {
$output .= "{$section_props}['step'] = 1;\n";
}
$initFor['index'] = "{$sectionVar}->value['index'] = {$propValue['start']}";
if (!isset($_attr['start'])) {
$output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
} else {
$output .= "if ({$section_props}['start'] < 0)\n" . " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . "else\n" . " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
}
$output .= "if ({$section_props}['show']) {\n";
if (!isset($_attr['start']) && !isset($_attr['step']) && !isset($_attr['max'])) {
$output .= " {$section_props}['total'] = {$section_props}['loop'];\n";
$propValue['total'] = $propValue['loop'];
$propType['total'] = $propType['loop'];
} else {
$output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
$propType['total'] = $propType['start'] + $propType['loop'] + $propType['step'] + $propType['max'];
if ($propType['total'] == 0) {
$propValue['total'] = min(ceil(($propValue['step'] > 0 ? $propValue['loop'] -
$propValue['start'] : (int) $propValue['start'] + 1) /
abs($propValue['step'])), $propValue['max']);
} else {
$total_code = array(1 => 'min(', 2 => 'ceil(', 3 => '(', 4 => "{$propValue['step']} > 0 ? ",
5 => $propValue['loop'], 6 => ' - ', 7 => $propValue['start'], 8 => ' : ',
9 => $propValue['start'], 10 => '+ 1', 11 => ')', 12 => '/ ', 13 => 'abs(',
14 => $propValue['step'], 15 => ')', 16 => ')', 17 => ", {$propValue['max']})",);
if (!isset($propValue['max'])) {
$total_code[1] = $total_code[17] = '';
}
if ($propType['loop'] + $propType['start'] == 0) {
$total_code[5] = $propValue['loop'] - $propValue['start'];
$total_code[6] = $total_code[7] = '';
}
if ($propType['start'] == 0) {
$total_code[9] = (int) $propValue['start'] + 1;
$total_code[10] = '';
}
if ($propType['step'] == 0) {
$total_code[13] = $total_code[15] = '';
if ($propValue['step'] == 1 || $propValue['step'] == - 1) {
$total_code[2] = $total_code[12] = $total_code[14] = $total_code[16] = '';
} elseif ($propValue['step'] < 0) {
$total_code[14] = - $propValue['step'];
}
$total_code[4] = '';
if ($propValue['step'] > 0) {
$total_code[8] = $total_code[9] = $total_code[10] = '';
} else {
$total_code[5] = $total_code[6] = $total_code[7] = $total_code[8] = '';
}
}
$propValue['total'] = join('', $total_code);
}
}
$output .= " if ({$section_props}['total'] == 0)\n" . " {$section_props}['show'] = false;\n" . "} else\n" . " {$section_props}['total'] = 0;\n";
$output .= "if ({$section_props}['show']):\n";
$output .= "
for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
{$section_props}['iteration'] <= {$section_props}['total'];
{$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
$output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
$output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
$output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
$output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n";
$output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n";
if (isset($namedAttr['total'])) {
$initNamedProperty['total'] = "'total' => {$propValue['total']}";
if ($propType['total'] > 0) {
$propValue['total'] = "{$sectionVar}->value['total']";
}
} elseif ($propType['total'] > 0) {
$initLocal['total'] = $propValue['total'];
$propValue['total'] = "{$local}total";
}
$cmpFor['iteration'] = "{$propValue['iteration']} <= {$propValue['total']}";
foreach ($initLocal as $key => $code) {
$output .= "{$local}{$key} = {$code};\n";
}
$_vars = 'array(' . join(', ', $initNamedProperty) . ')';
$output .= "{$sectionVar} = new Smarty_Variable({$_vars});\n";
$cond_code = "{$propValue['total']} != 0";
if ($propType['total'] == 0) {
if ($propValue['total'] == 0) {
$cond_code = 'false';
} else {
$cond_code = 'true';
}
}
if ($propType['show'] > 0) {
$output .= "{$local}show = {$propValue['show']} ? {$cond_code} : false;\n";
$output .= "if ({$local}show) {\n";
} elseif ($propValue['show'] == 'true') {
$output .= "if ({$cond_code}) {\n";
} else {
$output .= "if (false) {\n";
}
$jinit = join(', ', $initFor);
$jcmp = join(', ', $cmpFor);
$jinc = join(', ', $incFor);
$output .= "for ({$jinit}; {$jcmp}; {$jinc}){\n";
if (isset($namedAttr['rownum'])) {
$output .= "{$sectionVar}->value['rownum'] = {$propValue['iteration']};\n";
}
if (isset($namedAttr['index_prev'])) {
$output .= "{$sectionVar}->value['index_prev'] = {$propValue['index']} - {$propValue['step']};\n";
}
if (isset($namedAttr['index_next'])) {
$output .= "{$sectionVar}->value['index_next'] = {$propValue['index']} + {$propValue['step']};\n";
}
if (isset($namedAttr['first'])) {
$output .= "{$sectionVar}->value['first'] = ({$propValue['iteration']} == 1);\n";
}
if (isset($namedAttr['last'])) {
$output .= "{$sectionVar}->value['last'] = ({$propValue['iteration']} == {$propValue['total']});\n";
}
$output .= "?>";
return $output;
@@ -152,20 +394,20 @@ class Smarty_Internal_Compile_Sectionelse extends Smarty_Internal_CompileBase
/**
* Compiles code for the {sectionelse} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string compiled code
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
list($openTag, $nocache) = $this->closeTag($compiler, array('section'));
$this->openTag($compiler, 'sectionelse', array('sectionelse', $nocache));
list($openTag, $nocache, $local, $sectionVar) = $this->closeTag($compiler, array('section'));
$this->openTag($compiler, 'sectionelse', array('sectionelse', $nocache, $local, $sectionVar));
return "<?php endfor; else: ?>";
return "<?php }} else {\n ?>";
}
}
@@ -180,27 +422,33 @@ class Smarty_Internal_Compile_Sectionclose extends Smarty_Internal_CompileBase
/**
* Compiles code for the {/section} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string compiled code
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$compiler->loopNesting--;
// must endblock be nocache?
if ($compiler->nocache) {
$compiler->tag_nocache = true;
}
list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('section', 'sectionelse'));
list($openTag, $compiler->nocache, $local, $sectionVar) = $this->closeTag($compiler, array('section',
'sectionelse'));
$output = "<?php\n";
if ($openTag == 'sectionelse') {
return "<?php endif; ?>";
$output .= "}\n";
} else {
return "<?php endfor; endif; ?>";
$output .= "}\n}\n";
}
$output .= "if ({$local}saved) {\n";
$output .= "{$sectionVar} = {$local}saved;\n";
$output .= "}\n";
$output .= "?>";
return $output;
}
}
@@ -25,10 +25,10 @@ class Smarty_Internal_Compile_Setfilter extends Smarty_Internal_CompileBase
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
$compiler->variable_filter_stack[] = $compiler->template->variable_filters;
$compiler->template->variable_filters = $parameter['modifier_list'];
$compiler->variable_filter_stack[] = $compiler->variable_filters;
$compiler->variable_filters = $parameter['modifier_list'];
// this tag does not return compiled code
$compiler->has_code = false;
@@ -53,14 +53,14 @@ class Smarty_Internal_Compile_Setfilterclose extends Smarty_Internal_CompileBase
*
* @return string compiled code
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
$_attr = $this->getAttributes($compiler, $args);
// reset variable filter to previous state
if (count($compiler->variable_filter_stack)) {
$compiler->template->variable_filters = array_pop($compiler->variable_filter_stack);
$compiler->variable_filters = array_pop($compiler->variable_filter_stack);
} else {
$compiler->template->variable_filters = array();
$compiler->variable_filters = array();
}
// this tag does not return compiled code
$compiler->has_code = false;
@@ -0,0 +1,46 @@
<?php
/**
* Smarty Internal Plugin Compile Shared Inheritance
* Shared methods for {extends} and {block} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Shared Inheritance Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Shared_Inheritance extends Smarty_Internal_CompileBase
{
/**
* Register post compile callback to compile inheritance initialization code
*
* @param \Smarty_Internal_TemplateCompilerBase $compiler
* @param bool|false $initChildSequence if true force child template
*/
public function registerInit(Smarty_Internal_TemplateCompilerBase $compiler, $initChildSequence = false)
{
if ($initChildSequence || !isset($compiler->_cache['inheritanceInit'])) {
$compiler->registerPostCompileCallback(array('Smarty_Internal_Compile_Shared_Inheritance', 'postCompile'),
array($initChildSequence), 'inheritanceInit', $initChildSequence);
$compiler->_cache['inheritanceInit'] = true;
}
}
/**
* Compile inheritance initialization code as prefix
*
* @param \Smarty_Internal_TemplateCompilerBase $compiler
* @param bool|false $initChildSequence if true force child template
*/
static function postCompile(Smarty_Internal_TemplateCompilerBase $compiler, $initChildSequence = false)
{
$compiler->prefixCompiledCode .= "<?php \$_smarty_tpl->ext->_inheritance->init(\$_smarty_tpl, " .
var_export($initChildSequence, true) . ");\n?>\n";
}
}
@@ -19,48 +19,63 @@ class Smarty_Internal_Compile_While extends Smarty_Internal_CompileBase
/**
* Compiles code for the {while} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
* @throws \SmartyCompilerException
*/
public function compile($args, $compiler, $parameter)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{
$compiler->loopNesting++;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$this->openTag($compiler, 'while', $compiler->nocache);
if (!array_key_exists("if condition", $parameter)) {
$compiler->trigger_template_error("missing while condition", $compiler->lex->taglineno);
$compiler->trigger_template_error("missing while condition", null, true);
}
// maybe nocache because of nocache variables
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
$_output = "<?php\n";
if (is_array($parameter['if condition'])) {
if ($compiler->nocache) {
$_nocache = ',true';
// create nocache var to make it know for further compiling
if (is_array($parameter['if condition']['var'])) {
$compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true);
$var = trim($parameter['if condition']['var']['var'], "'");
} else {
$compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true);
$var = trim($parameter['if condition']['var'], "'");
}
if (isset($compiler->template->tpl_vars[$var])) {
$compiler->template->tpl_vars[$var]->nocache = true;
} else {
$compiler->template->tpl_vars[$var] = new Smarty_Variable(null, true);
}
} else {
$_nocache = '';
}
if (is_array($parameter['if condition']['var'])) {
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n";
$_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . ") {?>";
$_output .= "if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] .
"]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] .
"]->value)) \$_smarty_tpl->smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, " . $parameter['if condition']['var']['var'] .
"$_nocache);\n";
$_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" .
$parameter['if condition']['var']['smarty_internal_index'] . " = " .
$parameter['if condition']['value'] . ") {?>";
} else {
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});";
$_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . ") {?>";
$_output .= "if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] .
"])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] .
"] = new Smarty_Variable(null{$_nocache});";
$_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " .
$parameter['if condition']['value'] . ") {?>";
}
return $_output;
} else {
return "<?php while ({$parameter['if condition']}) {?>";
}
$_output .= "while ({$parameter['if condition']}) {?>";
}
return $_output;
}
}
@@ -75,19 +90,19 @@ class Smarty_Internal_Compile_Whileclose extends Smarty_Internal_CompileBase
/**
* Compiles code for the {/while} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $args array with attributes from parser
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @return string compiled code
*/
public function compile($args, $compiler)
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
{
$compiler->loopNesting--;
// must endblock be nocache?
if ($compiler->nocache) {
$compiler->tag_nocache = true;
}
$compiler->nocache = $this->closeTag($compiler, array('while'));
return "<?php }?>";
return "<?php }?>\n";
}
}
@@ -21,6 +21,7 @@ abstract class Smarty_Internal_CompileBase
* @var array
*/
public $required_attributes = array();
/**
* Array of names of optional attribute required by tag
* use array('_any') if there is no restriction of attributes names
@@ -28,12 +29,14 @@ abstract class Smarty_Internal_CompileBase
* @var array
*/
public $optional_attributes = array();
/**
* Shorttag attribute order defined by its names
*
* @var array
*/
public $shorttag_order = array();
/**
* Array of names of valid option flags
*
@@ -68,7 +71,7 @@ abstract class Smarty_Internal_CompileBase
$_indexed_attr[$this->shorttag_order[$key]] = $mixed;
} else {
// too many shorthands
$compiler->trigger_template_error('too many shorthand attributes', $compiler->lex->taglineno);
$compiler->trigger_template_error('too many shorthand attributes', null, true);
}
// named attribute
} else {
@@ -90,7 +93,7 @@ abstract class Smarty_Internal_CompileBase
$_indexed_attr[$kv['key']] = false;
}
} else {
$compiler->trigger_template_error("illegal value of option flag \"{$kv['key']}\"", $compiler->lex->taglineno);
$compiler->trigger_template_error("illegal value of option flag \"{$kv['key']}\"", null, true);
}
// must be named attribute
} else {
@@ -102,7 +105,7 @@ abstract class Smarty_Internal_CompileBase
// check if all required attributes present
foreach ($this->required_attributes as $attr) {
if (!array_key_exists($attr, $_indexed_attr)) {
$compiler->trigger_template_error("missing \"" . $attr . "\" attribute", $compiler->lex->taglineno);
$compiler->trigger_template_error("missing \"" . $attr . "\" attribute", null, true);
}
}
// check for not allowed attributes
@@ -110,7 +113,7 @@ abstract class Smarty_Internal_CompileBase
$tmp_array = array_merge($this->required_attributes, $this->optional_attributes, $this->option_flags);
foreach ($_indexed_attr as $key => $dummy) {
if (!in_array($key, $tmp_array) && $key !== 0) {
$compiler->trigger_template_error("unexpected \"" . $key . "\" attribute", $compiler->lex->taglineno);
$compiler->trigger_template_error("unexpected \"" . $key . "\" attribute", null, true);
}
}
}
@@ -162,12 +165,13 @@ abstract class Smarty_Internal_CompileBase
}
}
// wrong nesting of tags
$compiler->trigger_template_error("unclosed {$compiler->smarty->left_delimiter}" . $_openTag . "{$compiler->smarty->right_delimiter} tag");
$compiler->trigger_template_error("unclosed {$compiler->smarty->left_delimiter}" . $_openTag .
"{$compiler->smarty->right_delimiter} tag");
return;
}
// wrong nesting of tags
$compiler->trigger_template_error("unexpected closing tag", $compiler->lex->taglineno);
$compiler->trigger_template_error("unexpected closing tag", null, true);
return;
}
-306
View File
@@ -1,306 +0,0 @@
<?php
/**
* Smarty Internal Plugin Config
*
* @package Smarty
* @subpackage Config
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Config
* Main class for config variables
*
* @package Smarty
* @subpackage Config
* @ignore
*/
class Smarty_Internal_Config
{
/**
* Smarty instance
*
* @var Smarty object
*/
public $smarty = null;
/**
* Object of config var storage
*
* @var object
*/
public $data = null;
/**
* Config resource
*
* @var string
*/
public $config_resource = null;
/**
* Compiled config file
*
* @var string
*/
public $compiled_config = null;
/**
* filepath of compiled config file
*
* @var string
*/
public $compiled_filepath = null;
/**
* Filemtime of compiled config Filemtime
*
* @var int
*/
public $compiled_timestamp = null;
/**
* flag if compiled config file is invalid and must be (re)compiled
*
* @var bool
*/
public $mustCompile = null;
/**
* Config file compiler object
*
* @var Smarty_Internal_Config_File_Compiler object
*/
public $compiler_object = null;
/**
* Constructor of config file object
*
* @param string $config_resource config file resource name
* @param Smarty $smarty Smarty instance
* @param object $data object for config vars storage
*/
public function __construct($config_resource, $smarty, $data = null)
{
$this->data = $data;
$this->smarty = $smarty;
$this->config_resource = $config_resource;
}
/**
* Returns the compiled filepath
*
* @return string the compiled filepath
*/
public function getCompiledFilepath()
{
return $this->compiled_filepath === null ?
($this->compiled_filepath = $this->buildCompiledFilepath()) :
$this->compiled_filepath;
}
/**
* Get file path.
*
* @return string
*/
public function buildCompiledFilepath()
{
$_compile_id = isset($this->smarty->compile_id) ? preg_replace('![^\w\|]+!', '_', $this->smarty->compile_id) : null;
$_flag = (int) $this->smarty->config_read_hidden + (int) $this->smarty->config_booleanize * 2
+ (int) $this->smarty->config_overwrite * 4;
$_filepath = sha1(realpath($this->source->filepath) . $_flag);
// if use_sub_dirs, break file into directories
if ($this->smarty->use_sub_dirs) {
$_filepath = substr($_filepath, 0, 2) . DS
. substr($_filepath, 2, 2) . DS
. substr($_filepath, 4, 2) . DS
. $_filepath;
}
$_compile_dir_sep = $this->smarty->use_sub_dirs ? DS : '^';
if (isset($_compile_id)) {
$_filepath = $_compile_id . $_compile_dir_sep . $_filepath;
}
$_compile_dir = $this->smarty->getCompileDir();
return $_compile_dir . $_filepath . '.' . basename($this->source->name) . '.config' . '.php';
}
/**
* Returns the timestamp of the compiled file
*
* @return integer the file timestamp
*/
public function getCompiledTimestamp()
{
return $this->compiled_timestamp === null
? ($this->compiled_timestamp = (file_exists($this->getCompiledFilepath())) ? filemtime($this->getCompiledFilepath()) : false)
: $this->compiled_timestamp;
}
/**
* Returns if the current config file must be compiled
* It does compare the timestamps of config source and the compiled config and checks the force compile configuration
*
* @return boolean true if the file must be compiled
*/
public function mustCompile()
{
return $this->mustCompile === null ?
$this->mustCompile = ($this->smarty->force_compile || $this->getCompiledTimestamp() === false || $this->smarty->compile_check && $this->getCompiledTimestamp() < $this->source->timestamp) :
$this->mustCompile;
}
/**
* Returns the compiled config file
* It checks if the config file must be compiled or just read the compiled version
*
* @return string the compiled config file
*/
public function getCompiledConfig()
{
if ($this->compiled_config === null) {
// see if template needs compiling.
if ($this->mustCompile()) {
$this->compileConfigSource();
} else {
$this->compiled_config = file_get_contents($this->getCompiledFilepath());
}
}
return $this->compiled_config;
}
/**
* Compiles the config files
*
* @throws Exception
*/
public function compileConfigSource()
{
// compile template
if (!is_object($this->compiler_object)) {
// load compiler
$this->compiler_object = new Smarty_Internal_Config_File_Compiler($this->smarty);
}
// compile locking
if ($this->smarty->compile_locking) {
if ($saved_timestamp = $this->getCompiledTimestamp()) {
touch($this->getCompiledFilepath());
}
}
// call compiler
try {
$this->compiler_object->compileSource($this);
}
catch (Exception $e) {
// restore old timestamp in case of error
if ($this->smarty->compile_locking && $saved_timestamp) {
touch($this->getCompiledFilepath(), $saved_timestamp);
}
throw $e;
}
// compiling succeeded
// write compiled template
Smarty_Internal_Write_File::writeFile($this->getCompiledFilepath(), $this->getCompiledConfig(), $this->smarty);
}
/**
* load config variables
*
* @param mixed $sections array of section names, single section or null
* @param string $scope global,parent or local
*
* @throws Exception
*/
public function loadConfigVars($sections = null, $scope = 'local')
{
if ($this->data instanceof Smarty_Internal_Template) {
$this->data->properties['file_dependency'][sha1($this->source->filepath)] = array($this->source->filepath, $this->source->timestamp, 'file');
}
if ($this->mustCompile()) {
$this->compileConfigSource();
}
// pointer to scope
if ($scope == 'local') {
$scope_ptr = $this->data;
} elseif ($scope == 'parent') {
if (isset($this->data->parent)) {
$scope_ptr = $this->data->parent;
} else {
$scope_ptr = $this->data;
}
} elseif ($scope == 'root' || $scope == 'global') {
$scope_ptr = $this->data;
while (isset($scope_ptr->parent)) {
$scope_ptr = $scope_ptr->parent;
}
}
$_config_vars = array();
include($this->getCompiledFilepath());
// copy global config vars
foreach ($_config_vars['vars'] as $variable => $value) {
if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
$scope_ptr->config_vars[$variable] = $value;
} else {
$scope_ptr->config_vars[$variable] = array_merge((array) $scope_ptr->config_vars[$variable], (array) $value);
}
}
// scan sections
if (!empty($sections)) {
foreach ((array) $sections as $this_section) {
if (isset($_config_vars['sections'][$this_section])) {
foreach ($_config_vars['sections'][$this_section]['vars'] as $variable => $value) {
if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
$scope_ptr->config_vars[$variable] = $value;
} else {
$scope_ptr->config_vars[$variable] = array_merge((array) $scope_ptr->config_vars[$variable], (array) $value);
}
}
}
}
}
}
/**
* set Smarty property in template context
*
* @param string $property_name property name
* @param mixed $value value
*
* @throws SmartyException if $property_name is not valid
*/
public function __set($property_name, $value)
{
switch ($property_name) {
case 'source':
case 'compiled':
$this->$property_name = $value;
return;
}
throw new SmartyException("invalid config property '$property_name'.");
}
/**
* get Smarty property in template context
*
* @param string $property_name property name
*
* @return \Smarty_Config_Source|\Smarty_Template_Compiled
* @throws SmartyException if $property_name is not valid
*/
public function __get($property_name)
{
switch ($property_name) {
case 'source':
if (empty($this->config_resource)) {
throw new SmartyException("Unable to parse resource name \"{$this->config_resource}\"");
}
$this->source = Smarty_Resource::config($this);
return $this->source;
case 'compiled':
$this->compiled = $this->source->getCompiled($this);
return $this->compiled;
}
throw new SmartyException("config attribute '$property_name' does not exist.");
}
}
@@ -17,6 +17,20 @@
*/
class Smarty_Internal_Config_File_Compiler
{
/**
* Lexer class name
*
* @var string
*/
public $lexer_class;
/**
* Parser class name
*
* @var string
*/
public $parser_class;
/**
* Lexer object
*
@@ -41,9 +55,9 @@ class Smarty_Internal_Config_File_Compiler
/**
* Smarty object
*
* @var Smarty_Internal_Config object
* @var Smarty_Internal_Template object
*/
public $config;
public $template;
/**
* Compiled config data sections and variables
@@ -52,40 +66,53 @@ class Smarty_Internal_Config_File_Compiler
*/
public $config_data = array();
/**
* compiled config data must always be written
*
* @var bool
*/
public $write_compiled_code = true;
/**
* Initialize compiler
*
* @param Smarty $smarty base instance
* @param string $lexer_class class name
* @param string $parser_class class name
* @param Smarty $smarty global instance
*/
public function __construct($smarty)
public function __construct($lexer_class, $parser_class, Smarty $smarty)
{
$this->smarty = $smarty;
// get required plugins
$this->lexer_class = $lexer_class;
$this->parser_class = $parser_class;
$this->smarty = $smarty;
$this->config_data['sections'] = array();
$this->config_data['vars'] = array();
}
/**
* Method to compile a Smarty template.
* Method to compile Smarty config source.
*
* @param Smarty_Internal_Config $config config object
* @param Smarty_Internal_Template $template
*
* @return bool true if compiling succeeded, false if it failed
* @return bool true if compiling succeeded, false if it failed
*/
public function compileSource(Smarty_Internal_Config $config)
public function compileTemplate(Smarty_Internal_Template $template)
{
/* here is where the compiling takes place. Smarty
tags in the templates are replaces with PHP code,
then written to compiled files. */
$this->config = $config;
// get config file source
$_content = $config->source->content . "\n";
// on empty template just return
if ($_content == '') {
return true;
$this->template = $template;
$this->template->compiled->file_dependency[$this->template->source->uid] = array($this->template->source->filepath,
$this->template->source->getTimeStamp(),
$this->template->source->type);
if ($this->smarty->debugging) {
$this->smarty->_debug->start_compile($this->template);
}
// init the lexer/parser to compile the config file
$lex = new Smarty_Internal_Configfilelexer($_content, $this);
$parser = new Smarty_Internal_Configfileparser($lex, $this);
/* @var Smarty_Internal_ConfigFileLexer $lex */
$lex = new $this->lexer_class(str_replace(array("\r\n", "\r"), "\n", $template->source->getContent()) .
"\n", $this);
/* @var Smarty_Internal_ConfigFileParser $parser */
$parser = new $this->parser_class($lex, $this);
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
$mbEncoding = mb_internal_encoding();
@@ -94,7 +121,6 @@ class Smarty_Internal_Config_File_Compiler
$mbEncoding = null;
}
if ($this->smarty->_parserdebug) {
$parser->PrintTrace();
}
@@ -111,8 +137,17 @@ class Smarty_Internal_Config_File_Compiler
if ($mbEncoding) {
mb_internal_encoding($mbEncoding);
}
if ($this->smarty->debugging) {
$this->smarty->_debug->end_compile($this->template);
}
// template header code
$template_header = "<?php /* Smarty version " . Smarty::SMARTY_VERSION . ", created on " .
strftime("%Y-%m-%d %H:%M:%S") . "\n";
$template_header .= " compiled from \"" . $this->template->source->filepath . "\" */ ?>\n";
$config->compiled_config = '<?php $_config_vars = ' . var_export($this->config_data, true) . '; ?>';
$code = '<?php $_smarty_tpl->smarty->ext->configLoad->_loadConfigVars($_smarty_tpl, ' .
var_export($this->config_data, true) . '); ?>';
return $template_header . $this->template->smarty->ext->_codeFrame->create($this->template, $code);
}
/**
@@ -129,13 +164,13 @@ class Smarty_Internal_Config_File_Compiler
{
$this->lex = Smarty_Internal_Configfilelexer::instance();
$this->parser = Smarty_Internal_Configfileparser::instance();
// get template source line which has error
// get config source line which has error
$line = $this->lex->line;
if (isset($args)) {
// $line--;
}
$match = preg_split("/\n/", $this->lex->data);
$error_text = "Syntax error in config file '{$this->config->source->filepath}' on line {$line} '{$match[$line - 1]}' ";
$error_text = "Syntax error in config file '{$this->template->source->filepath}' on line {$line} '{$match[$line - 1]}' ";
if (isset($args)) {
// individual error message
$error_text .= $args;
@@ -1,6 +1,7 @@
<?php
/**
* Smarty Internal Plugin Configfilelexer
*
* This is the lexer to break the config file source into tokens
*
* @package Smarty
@@ -9,25 +10,134 @@
*/
/**
* Smarty Internal Plugin Configfilelexer
* Smarty_Internal_Configfilelexer
*
* This is the config file lexer.
* It is generated from the smarty_internal_configfilelexer.plex file
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
class Smarty_Internal_Configfilelexer
{
/**
* Source
*
* @var string
*/
public $data;
/**
* byte counter
*
* @var int
*/
public $counter;
/**
* token number
*
* @var int
*/
public $token;
/**
* token value
*
* @var string
*/
public $value;
public $node;
/**
* current line
*
* @var int
*/
public $line;
private $state = 1;
/**
* state number
*
* @var int
*/
public $state = 1;
/**
* Smarty object
*
* @var Smarty
*/
public $smarty = null;
/**
* compiler object
*
* @var Smarty_Internal_Config_File_Compiler
*/
private $compiler = null;
/**
* copy of config_booleanize
*
* @var bool
*/
private $configBooleanize = false;
/**
* trace file
*
* @var resource
*/
public $yyTraceFILE;
/**
* trace prompt
*
* @var string
*/
public $yyTracePrompt;
public $state_name = array(1 => 'START', 2 => 'VALUE', 3 => 'NAKED_STRING_VALUE', 4 => 'COMMENT', 5 => 'SECTION', 6 => 'TRIPPLE');
public $smarty_token_names = array( // Text for parser error messages
/**
* state names
*
* @var array
*/
public $state_name = array(1 => 'START', 2 => 'VALUE', 3 => 'NAKED_STRING_VALUE', 4 => 'COMMENT', 5 => 'SECTION',
6 => 'TRIPPLE');
/**
* storage for assembled token patterns
*
* @var sring
*/
private $yy_global_pattern1 = null;
private $yy_global_pattern2 = null;
private $yy_global_pattern3 = null;
private $yy_global_pattern4 = null;
private $yy_global_pattern5 = null;
private $yy_global_pattern6 = null;
/**
* token names
*
* @var array
*/
public $smarty_token_names = array( // Text for parser error messages
);
function __construct($data, $compiler)
/**
* constructor
*
* @param string $data template source
* @param Smarty_Internal_Config_File_Compiler $compiler
*/
function __construct($data, Smarty_Internal_Config_File_Compiler $compiler)
{
// set instance object
self::instance($this);
@@ -39,6 +149,7 @@ class Smarty_Internal_Configfilelexer
$this->line = 1;
$this->compiler = $compiler;
$this->smarty = $compiler->smarty;
$this->configBooleanize = $this->smarty->config_booleanize;
}
public static function &instance($new_instance = null)
@@ -57,6 +168,7 @@ class Smarty_Internal_Configfilelexer
}
private $_yy_state = 1;
private $_yy_stack = array();
public function yylex()
@@ -97,41 +209,28 @@ class Smarty_Internal_Configfilelexer
public function yylex1()
{
$tokenMap = array(
1 => 0,
2 => 0,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
7 => 0,
8 => 0,
);
if (!isset($this->yy_global_pattern1)) {
$this->yy_global_pattern1 = "/\G(#|;)|\G(\\[)|\G(\\])|\G(=)|\G([ \t\r]+)|\G(\n)|\G([0-9]*[a-zA-Z_]\\w*)|\G([\S\s])/isS";
}
if ($this->counter >= strlen($this->data)) {
return false; // end of input
}
$yy_global_pattern = "/\G(#|;)|\G(\\[)|\G(\\])|\G(=)|\G([ \t\r]+)|\G(\n)|\G([0-9]*[a-zA-Z_]\\w*)|\G([\S\s])/iS";
do {
if (preg_match($yy_global_pattern, $this->data, $yymatches, null, $this->counter)) {
if (preg_match($this->yy_global_pattern1, $this->data, $yymatches, null, $this->counter)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' .
' an empty string. Input "' . substr($this->data,
$this->counter, 5) . '... state START');
if (strlen($yysubmatches[0]) < 200) {
$yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
} else {
$yymatches = array_filter($yymatches, 'strlen');
}
if (empty($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state START');
}
next($yymatches); // skip global match
$this->token = key($yymatches); // token number
if ($tokenMap[$this->token]) {
// extract sub-patterns for passing to lex function
$yysubmatches = array_slice($yysubmatches, $this->token + 1,
$tokenMap[$this->token]);
} else {
$yysubmatches = array();
}
$this->value = current($yymatches); // token value
$r = $this->{'yy_r1_' . $this->token}($yysubmatches);
$r = $this->{'yy_r1_' . $this->token}();
if ($r === null) {
$this->counter += strlen($this->value);
$this->line += substr_count($this->value, "\n");
@@ -151,8 +250,7 @@ class Smarty_Internal_Configfilelexer
continue;
}
} else {
throw new Exception('Unexpected input at line' . $this->line .
': ' . $this->data[$this->counter]);
throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
}
break;
} while (true);
@@ -160,52 +258,52 @@ class Smarty_Internal_Configfilelexer
const START = 1;
function yy_r1_1($yy_subpatterns)
function yy_r1_1()
{
$this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
$this->yypushstate(self::COMMENT);
}
function yy_r1_2($yy_subpatterns)
function yy_r1_2()
{
$this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
$this->yypushstate(self::SECTION);
}
function yy_r1_3($yy_subpatterns)
function yy_r1_3()
{
$this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
}
function yy_r1_4($yy_subpatterns)
function yy_r1_4()
{
$this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
$this->yypushstate(self::VALUE);
}
function yy_r1_5($yy_subpatterns)
function yy_r1_5()
{
return false;
}
function yy_r1_6($yy_subpatterns)
function yy_r1_6()
{
$this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
}
function yy_r1_7($yy_subpatterns)
function yy_r1_7()
{
$this->token = Smarty_Internal_Configfileparser::TPC_ID;
}
function yy_r1_8($yy_subpatterns)
function yy_r1_8()
{
$this->token = Smarty_Internal_Configfileparser::TPC_OTHER;
@@ -213,42 +311,28 @@ class Smarty_Internal_Configfilelexer
public function yylex2()
{
$tokenMap = array(
1 => 0,
2 => 0,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
7 => 0,
8 => 0,
9 => 0,
);
if (!isset($this->yy_global_pattern2)) {
$this->yy_global_pattern2 = "/\G([ \t\r]+)|\G(\\d+\\.\\d+(?=[ \t\r]*[\n#;]))|\G(\\d+(?=[ \t\r]*[\n#;]))|\G(\"\"\")|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*'(?=[ \t\r]*[\n#;]))|\G(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"(?=[ \t\r]*[\n#;]))|\G([a-zA-Z]+(?=[ \t\r]*[\n#;]))|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/isS";
}
if ($this->counter >= strlen($this->data)) {
return false; // end of input
}
$yy_global_pattern = "/\G([ \t\r]+)|\G(\\d+\\.\\d+(?=[ \t\r]*[\n#;]))|\G(\\d+(?=[ \t\r]*[\n#;]))|\G(\"\"\")|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*'(?=[ \t\r]*[\n#;]))|\G(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"(?=[ \t\r]*[\n#;]))|\G([a-zA-Z]+(?=[ \t\r]*[\n#;]))|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/iS";
do {
if (preg_match($yy_global_pattern, $this->data, $yymatches, null, $this->counter)) {
if (preg_match($this->yy_global_pattern2, $this->data, $yymatches, null, $this->counter)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' .
' an empty string. Input "' . substr($this->data,
$this->counter, 5) . '... state VALUE');
if (strlen($yysubmatches[0]) < 200) {
$yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
} else {
$yymatches = array_filter($yymatches, 'strlen');
}
if (empty($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state VALUE');
}
next($yymatches); // skip global match
$this->token = key($yymatches); // token number
if ($tokenMap[$this->token]) {
// extract sub-patterns for passing to lex function
$yysubmatches = array_slice($yysubmatches, $this->token + 1,
$tokenMap[$this->token]);
} else {
$yysubmatches = array();
}
$this->value = current($yymatches); // token value
$r = $this->{'yy_r2_' . $this->token}($yysubmatches);
$r = $this->{'yy_r2_' . $this->token}();
if ($r === null) {
$this->counter += strlen($this->value);
$this->line += substr_count($this->value, "\n");
@@ -268,8 +352,7 @@ class Smarty_Internal_Configfilelexer
continue;
}
} else {
throw new Exception('Unexpected input at line' . $this->line .
': ' . $this->data[$this->counter]);
throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
}
break;
} while (true);
@@ -277,51 +360,53 @@ class Smarty_Internal_Configfilelexer
const VALUE = 2;
function yy_r2_1($yy_subpatterns)
function yy_r2_1()
{
return false;
}
function yy_r2_2($yy_subpatterns)
function yy_r2_2()
{
$this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
$this->yypopstate();
}
function yy_r2_3($yy_subpatterns)
function yy_r2_3()
{
$this->token = Smarty_Internal_Configfileparser::TPC_INT;
$this->yypopstate();
}
function yy_r2_4($yy_subpatterns)
function yy_r2_4()
{
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
$this->yypushstate(self::TRIPPLE);
}
function yy_r2_5($yy_subpatterns)
function yy_r2_5()
{
$this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
$this->yypopstate();
}
function yy_r2_6($yy_subpatterns)
function yy_r2_6()
{
$this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
$this->yypopstate();
}
function yy_r2_7($yy_subpatterns)
function yy_r2_7()
{
if (!$this->smarty->config_booleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes", "no"))) {
if (!$this->configBooleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes",
"no"))
) {
$this->yypopstate();
$this->yypushstate(self::NAKED_STRING_VALUE);
return true; //reprocess in new state
@@ -331,14 +416,14 @@ class Smarty_Internal_Configfilelexer
}
}
function yy_r2_8($yy_subpatterns)
function yy_r2_8()
{
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
$this->yypopstate();
}
function yy_r2_9($yy_subpatterns)
function yy_r2_9()
{
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
@@ -348,34 +433,28 @@ class Smarty_Internal_Configfilelexer
public function yylex3()
{
$tokenMap = array(
1 => 0,
);
if (!isset($this->yy_global_pattern3)) {
$this->yy_global_pattern3 = "/\G([^\n]+?(?=[ \t\r]*\n))/isS";
}
if ($this->counter >= strlen($this->data)) {
return false; // end of input
}
$yy_global_pattern = "/\G([^\n]+?(?=[ \t\r]*\n))/iS";
do {
if (preg_match($yy_global_pattern, $this->data, $yymatches, null, $this->counter)) {
if (preg_match($this->yy_global_pattern3, $this->data, $yymatches, null, $this->counter)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' .
' an empty string. Input "' . substr($this->data,
$this->counter, 5) . '... state NAKED_STRING_VALUE');
if (strlen($yysubmatches[0]) < 200) {
$yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
} else {
$yymatches = array_filter($yymatches, 'strlen');
}
if (empty($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state NAKED_STRING_VALUE');
}
next($yymatches); // skip global match
$this->token = key($yymatches); // token number
if ($tokenMap[$this->token]) {
// extract sub-patterns for passing to lex function
$yysubmatches = array_slice($yysubmatches, $this->token + 1,
$tokenMap[$this->token]);
} else {
$yysubmatches = array();
}
$this->value = current($yymatches); // token value
$r = $this->{'yy_r3_' . $this->token}($yysubmatches);
$r = $this->{'yy_r3_' . $this->token}();
if ($r === null) {
$this->counter += strlen($this->value);
$this->line += substr_count($this->value, "\n");
@@ -395,8 +474,7 @@ class Smarty_Internal_Configfilelexer
continue;
}
} else {
throw new Exception('Unexpected input at line' . $this->line .
': ' . $this->data[$this->counter]);
throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
}
break;
} while (true);
@@ -404,7 +482,7 @@ class Smarty_Internal_Configfilelexer
const NAKED_STRING_VALUE = 3;
function yy_r3_1($yy_subpatterns)
function yy_r3_1()
{
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
@@ -413,36 +491,28 @@ class Smarty_Internal_Configfilelexer
public function yylex4()
{
$tokenMap = array(
1 => 0,
2 => 0,
3 => 0,
);
if (!isset($this->yy_global_pattern4)) {
$this->yy_global_pattern4 = "/\G([ \t\r]+)|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/isS";
}
if ($this->counter >= strlen($this->data)) {
return false; // end of input
}
$yy_global_pattern = "/\G([ \t\r]+)|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/iS";
do {
if (preg_match($yy_global_pattern, $this->data, $yymatches, null, $this->counter)) {
if (preg_match($this->yy_global_pattern4, $this->data, $yymatches, null, $this->counter)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' .
' an empty string. Input "' . substr($this->data,
$this->counter, 5) . '... state COMMENT');
if (strlen($yysubmatches[0]) < 200) {
$yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
} else {
$yymatches = array_filter($yymatches, 'strlen');
}
if (empty($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state COMMENT');
}
next($yymatches); // skip global match
$this->token = key($yymatches); // token number
if ($tokenMap[$this->token]) {
// extract sub-patterns for passing to lex function
$yysubmatches = array_slice($yysubmatches, $this->token + 1,
$tokenMap[$this->token]);
} else {
$yysubmatches = array();
}
$this->value = current($yymatches); // token value
$r = $this->{'yy_r4_' . $this->token}($yysubmatches);
$r = $this->{'yy_r4_' . $this->token}();
if ($r === null) {
$this->counter += strlen($this->value);
$this->line += substr_count($this->value, "\n");
@@ -462,8 +532,7 @@ class Smarty_Internal_Configfilelexer
continue;
}
} else {
throw new Exception('Unexpected input at line' . $this->line .
': ' . $this->data[$this->counter]);
throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
}
break;
} while (true);
@@ -471,19 +540,19 @@ class Smarty_Internal_Configfilelexer
const COMMENT = 4;
function yy_r4_1($yy_subpatterns)
function yy_r4_1()
{
return false;
}
function yy_r4_2($yy_subpatterns)
function yy_r4_2()
{
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
}
function yy_r4_3($yy_subpatterns)
function yy_r4_3()
{
$this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
@@ -492,35 +561,28 @@ class Smarty_Internal_Configfilelexer
public function yylex5()
{
$tokenMap = array(
1 => 0,
2 => 0,
);
if (!isset($this->yy_global_pattern5)) {
$this->yy_global_pattern5 = "/\G(\\.)|\G(.*?(?=[\.=[\]\r\n]))/isS";
}
if ($this->counter >= strlen($this->data)) {
return false; // end of input
}
$yy_global_pattern = "/\G(\\.)|\G(.*?(?=[\.=[\]\r\n]))/iS";
do {
if (preg_match($yy_global_pattern, $this->data, $yymatches, null, $this->counter)) {
if (preg_match($this->yy_global_pattern5, $this->data, $yymatches, null, $this->counter)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' .
' an empty string. Input "' . substr($this->data,
$this->counter, 5) . '... state SECTION');
if (strlen($yysubmatches[0]) < 200) {
$yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
} else {
$yymatches = array_filter($yymatches, 'strlen');
}
if (empty($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state SECTION');
}
next($yymatches); // skip global match
$this->token = key($yymatches); // token number
if ($tokenMap[$this->token]) {
// extract sub-patterns for passing to lex function
$yysubmatches = array_slice($yysubmatches, $this->token + 1,
$tokenMap[$this->token]);
} else {
$yysubmatches = array();
}
$this->value = current($yymatches); // token value
$r = $this->{'yy_r5_' . $this->token}($yysubmatches);
$r = $this->{'yy_r5_' . $this->token}();
if ($r === null) {
$this->counter += strlen($this->value);
$this->line += substr_count($this->value, "\n");
@@ -540,8 +602,7 @@ class Smarty_Internal_Configfilelexer
continue;
}
} else {
throw new Exception('Unexpected input at line' . $this->line .
': ' . $this->data[$this->counter]);
throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
}
break;
} while (true);
@@ -549,13 +610,13 @@ class Smarty_Internal_Configfilelexer
const SECTION = 5;
function yy_r5_1($yy_subpatterns)
function yy_r5_1()
{
$this->token = Smarty_Internal_Configfileparser::TPC_DOT;
}
function yy_r5_2($yy_subpatterns)
function yy_r5_2()
{
$this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
@@ -564,35 +625,28 @@ class Smarty_Internal_Configfilelexer
public function yylex6()
{
$tokenMap = array(
1 => 0,
2 => 0,
);
if (!isset($this->yy_global_pattern6)) {
$this->yy_global_pattern6 = "/\G(\"\"\"(?=[ \t\r]*[\n#;]))|\G([\S\s])/isS";
}
if ($this->counter >= strlen($this->data)) {
return false; // end of input
}
$yy_global_pattern = "/\G(\"\"\"(?=[ \t\r]*[\n#;]))|\G([\S\s])/iS";
do {
if (preg_match($yy_global_pattern, $this->data, $yymatches, null, $this->counter)) {
if (preg_match($this->yy_global_pattern6, $this->data, $yymatches, null, $this->counter)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' .
' an empty string. Input "' . substr($this->data,
$this->counter, 5) . '... state TRIPPLE');
if (strlen($yysubmatches[0]) < 200) {
$yymatches = preg_grep("/(.|\s)+/", $yysubmatches);
} else {
$yymatches = array_filter($yymatches, 'strlen');
}
if (empty($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' . ' an empty string. Input "' . substr($this->data, $this->counter, 5) . '... state TRIPPLE');
}
next($yymatches); // skip global match
$this->token = key($yymatches); // token number
if ($tokenMap[$this->token]) {
// extract sub-patterns for passing to lex function
$yysubmatches = array_slice($yysubmatches, $this->token + 1,
$tokenMap[$this->token]);
} else {
$yysubmatches = array();
}
$this->value = current($yymatches); // token value
$r = $this->{'yy_r6_' . $this->token}($yysubmatches);
$r = $this->{'yy_r6_' . $this->token}();
if ($r === null) {
$this->counter += strlen($this->value);
$this->line += substr_count($this->value, "\n");
@@ -612,8 +666,7 @@ class Smarty_Internal_Configfilelexer
continue;
}
} else {
throw new Exception('Unexpected input at line' . $this->line .
': ' . $this->data[$this->counter]);
throw new Exception('Unexpected input at line' . $this->line . ': ' . $this->data[$this->counter]);
}
break;
} while (true);
@@ -621,7 +674,7 @@ class Smarty_Internal_Configfilelexer
const TRIPPLE = 6;
function yy_r6_1($yy_subpatterns)
function yy_r6_1()
{
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
@@ -629,7 +682,7 @@ class Smarty_Internal_Configfilelexer
$this->yypushstate(self::START);
}
function yy_r6_2($yy_subpatterns)
function yy_r6_2()
{
$to = strlen($this->data);
@@ -642,5 +695,5 @@ class Smarty_Internal_Configfilelexer
$this->value = substr($this->data, $this->counter, $to - $this->counter);
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
}
}
}
File diff suppressed because it is too large Load Diff
+121 -472
View File
@@ -13,34 +13,70 @@
*
* @package Smarty
* @subpackage Template
*
* @method mixed getConfigVars(string $varName = null, bool $searchParents = true)
* @method mixed getStreamVariable(string $variable)
* @method Smarty_Internal_Data clearAssign(mixed $tpl_var)
* @method Smarty_Internal_Data clearAllAssign()
* @method Smarty_Internal_Data clearConfig(string $varName = null)
* @method Smarty_Internal_Data configLoad(string $config_file, mixed $sections = null, string $scope = 'local')
* @property int $scope
*/
class Smarty_Internal_Data
{
/**
* This object type (Smarty = 1, template = 2, data = 4)
*
* @var int
*/
public $_objType = 4;
/**
* name of class used for templates
*
* @var string
*/
public $template_class = 'Smarty_Internal_Template';
/**
* template variables
*
* @var array
* @var Smarty_Variable[]
*/
public $tpl_vars = array();
/**
* parent template (if any)
*
* @var Smarty_Internal_Template
* @var Smarty|Smarty_Internal_Template|Smarty_Internal_Data
*/
public $parent = null;
/**
* configuration settings
*
* @var array
* @var string[]
*/
public $config_vars = array();
/**
* extension handler
*
* @var Smarty_Internal_Extension_Handler
*/
public $ext = null;
/**
* Smarty_Internal_Data constructor.
*
* Install extension handler
*/
public function __construct()
{
$this->ext = new Smarty_Internal_Extension_Handler();
$this->ext->objType = $this->_objType;
}
/**
* assigns a Smarty variable
*
@@ -48,127 +84,62 @@ class Smarty_Internal_Data
* @param mixed $value the value to assign
* @param boolean $nocache if true any output of this variable will be not cached
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for
* chaining
*/
public function assign($tpl_var, $value = null, $nocache = false)
{
if (is_array($tpl_var)) {
foreach ($tpl_var as $_key => $_val) {
if ($_key != '') {
$this->tpl_vars[$_key] = new Smarty_variable($_val, $nocache);
$this->tpl_vars[$_key] = new Smarty_Variable($_val, $nocache);
if ($this->_objType == 2 && $this->scope) {
$this->ext->_updateScope->updateScope($this, $_key);
}
}
}
} else {
if ($tpl_var != '') {
$this->tpl_vars[$tpl_var] = new Smarty_variable($value, $nocache);
$this->tpl_vars[$tpl_var] = new Smarty_Variable($value, $nocache);
if ($this->_objType == 2 && $this->scope) {
$this->ext->_updateScope->updateScope($this, $tpl_var);
}
}
}
return $this;
}
/**
* assigns a global Smarty variable
*
* @param string $varname the global variable name
* @param mixed $value the value to assign
* @param boolean $nocache if true any output of this variable will be not cached
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
*/
public function assignGlobal($varname, $value = null, $nocache = false)
{
if ($varname != '') {
Smarty::$global_tpl_vars[$varname] = new Smarty_variable($value, $nocache);
$ptr = $this;
while ($ptr instanceof Smarty_Internal_Template) {
$ptr->tpl_vars[$varname] = clone Smarty::$global_tpl_vars[$varname];
$ptr = $ptr->parent;
}
}
return $this;
}
/**
* assigns values to template variables by reference
*
* @param string $tpl_var the template variable name
* @param $value
* @param boolean $nocache if true any output of this variable will be not cached
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
*/
public function assignByRef($tpl_var, &$value, $nocache = false)
{
if ($tpl_var != '') {
$this->tpl_vars[$tpl_var] = new Smarty_variable(null, $nocache);
$this->tpl_vars[$tpl_var]->value = & $value;
}
return $this;
}
/**
* appends values to template variables
*
* @param array|string $tpl_var the template variable name(s)
* @param mixed $value the value to append
* @param boolean $merge flag if array elements shall be merged
* @param boolean $nocache if true any output of this variable will be not cached
* @api Smarty::append()
* @link http://www.smarty.net/docs/en/api.append.tpl
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
* @param array|string $tpl_var the template variable name(s)
* @param mixed $value the value to append
* @param bool $merge flag if array elements shall be merged
* @param bool $nocache if true any output of this variable will
* be not cached
*
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public function append($tpl_var, $value = null, $merge = false, $nocache = false)
{
if (is_array($tpl_var)) {
// $tpl_var is an array, ignore $value
foreach ($tpl_var as $_key => $_val) {
if ($_key != '') {
if (!isset($this->tpl_vars[$_key])) {
$tpl_var_inst = $this->getVariable($_key, null, true, false);
if ($tpl_var_inst instanceof Undefined_Smarty_Variable) {
$this->tpl_vars[$_key] = new Smarty_variable(null, $nocache);
} else {
$this->tpl_vars[$_key] = clone $tpl_var_inst;
}
}
if (!(is_array($this->tpl_vars[$_key]->value) || $this->tpl_vars[$_key]->value instanceof ArrayAccess)) {
settype($this->tpl_vars[$_key]->value, 'array');
}
if ($merge && is_array($_val)) {
foreach ($_val as $_mkey => $_mval) {
$this->tpl_vars[$_key]->value[$_mkey] = $_mval;
}
} else {
$this->tpl_vars[$_key]->value[] = $_val;
}
}
}
} else {
if ($tpl_var != '' && isset($value)) {
if (!isset($this->tpl_vars[$tpl_var])) {
$tpl_var_inst = $this->getVariable($tpl_var, null, true, false);
if ($tpl_var_inst instanceof Undefined_Smarty_Variable) {
$this->tpl_vars[$tpl_var] = new Smarty_variable(null, $nocache);
} else {
$this->tpl_vars[$tpl_var] = clone $tpl_var_inst;
}
}
if (!(is_array($this->tpl_vars[$tpl_var]->value) || $this->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) {
settype($this->tpl_vars[$tpl_var]->value, 'array');
}
if ($merge && is_array($value)) {
foreach ($value as $_mkey => $_mval) {
$this->tpl_vars[$tpl_var]->value[$_mkey] = $_mval;
}
} else {
$this->tpl_vars[$tpl_var]->value[] = $value;
}
}
}
return $this->ext->append->append($this, $tpl_var, $value, $merge, $nocache);
}
return $this;
/**
* assigns a global Smarty variable
*
* @param string $varName the global variable name
* @param mixed $value the value to assign
* @param boolean $nocache if true any output of this variable will be not cached
*
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public function assignGlobal($varName, $value = null, $nocache = false)
{
return $this->ext->assignGlobal->assignGlobal($this, $varName, $value, $nocache);
}
/**
@@ -178,399 +149,77 @@ class Smarty_Internal_Data
* @param mixed &$value the referenced value to append
* @param boolean $merge flag if array elements shall be merged
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public function appendByRef($tpl_var, &$value, $merge = false)
{
if ($tpl_var != '' && isset($value)) {
if (!isset($this->tpl_vars[$tpl_var])) {
$this->tpl_vars[$tpl_var] = new Smarty_variable();
}
if (!is_array($this->tpl_vars[$tpl_var]->value)) {
settype($this->tpl_vars[$tpl_var]->value, 'array');
}
if ($merge && is_array($value)) {
foreach ($value as $_key => $_val) {
$this->tpl_vars[$tpl_var]->value[$_key] = & $value[$_key];
}
} else {
$this->tpl_vars[$tpl_var]->value[] = & $value;
}
}
return $this->ext->appendByRef->appendByRef($this, $tpl_var, $value, $merge);
}
return $this;
/**
* assigns values to template variables by reference
*
* @param string $tpl_var the template variable name
* @param $value
* @param boolean $nocache if true any output of this variable will be not cached
*
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public function assignByRef($tpl_var, &$value, $nocache = false)
{
return $this->ext->assignByRef->assignByRef($this, $tpl_var, $value, $nocache);
}
/**
* Returns a single or all template variables
*
* @param string $varname variable name or null
* @param object $_ptr optional pointer to data object
* @param boolean $search_parents include parent templates?
* @api Smarty::getTemplateVars()
* @link http://www.smarty.net/docs/en/api.get.template.vars.tpl
*
* @return string variable value or or array of variables
* @param string $varName variable name or null
* @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $_ptr optional pointer to data object
* @param bool $searchParents include parent templates?
*
* @return mixed variable value or or array of variables
*/
public function getTemplateVars($varname = null, $_ptr = null, $search_parents = true)
public function getTemplateVars($varName = null, Smarty_Internal_Data $_ptr = null, $searchParents = true)
{
if (isset($varname)) {
$_var = $this->getVariable($varname, $_ptr, $search_parents, false);
if (is_object($_var)) {
return $_var->value;
} else {
return null;
return $this->ext->getTemplateVars->getTemplateVars($this, $varName, $_ptr, $searchParents);
}
/**
* Follow the parent chain an merge template and config variables
*
* @param \Smarty_Internal_Data|null $data
*/
public function _mergeVars(Smarty_Internal_Data $data = null)
{
if (isset($data)) {
if (!empty($this->tpl_vars)) {
$data->tpl_vars = array_merge($this->tpl_vars, $data->tpl_vars);
}
if (!empty($this->config_vars)) {
$data->config_vars = array_merge($this->config_vars, $data->config_vars);
}
} else {
$_result = array();
if ($_ptr === null) {
$_ptr = $this;
}
while ($_ptr !== null) {
foreach ($_ptr->tpl_vars AS $key => $var) {
if (!array_key_exists($key, $_result)) {
$_result[$key] = $var->value;
}
}
// not found, try at parent
if ($search_parents) {
$_ptr = $_ptr->parent;
} else {
$_ptr = null;
}
}
if ($search_parents && isset(Smarty::$global_tpl_vars)) {
foreach (Smarty::$global_tpl_vars AS $key => $var) {
if (!array_key_exists($key, $_result)) {
$_result[$key] = $var->value;
}
}
}
return $_result;
$data = $this;
}
if (isset($this->parent)) {
$this->parent->_mergeVars($data);
}
}
/**
* clear the given assigned template variable.
* Handle unknown class methods
*
* @param string|array $tpl_var the template variable(s) to clear
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
*/
public function clearAssign($tpl_var)
{
if (is_array($tpl_var)) {
foreach ($tpl_var as $curr_var) {
unset($this->tpl_vars[$curr_var]);
}
} else {
unset($this->tpl_vars[$tpl_var]);
}
return $this;
}
/**
* clear all the assigned template variables.
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
*/
public function clearAllAssign()
{
$this->tpl_vars = array();
return $this;
}
/**
* load a config file, optionally load just selected sections
*
* @param string $config_file filename
* @param mixed $sections array of section names, single section or null
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
*/
public function configLoad($config_file, $sections = null)
{
// load Config class
$config = new Smarty_Internal_Config($config_file, $this->smarty, $this);
$config->loadConfigVars($sections);
return $this;
}
/**
* gets the object of a Smarty variable
*
* @param string $variable the name of the Smarty variable
* @param object $_ptr optional pointer to data object
* @param boolean $search_parents search also in parent data
* @param bool $error_enable
*
* @return object the object of the variable
*/
public function getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true)
{
if ($_ptr === null) {
$_ptr = $this;
}
while ($_ptr !== null) {
if (isset($_ptr->tpl_vars[$variable])) {
// found it, return it
return $_ptr->tpl_vars[$variable];
}
// not found, try at parent
if ($search_parents) {
$_ptr = $_ptr->parent;
} else {
$_ptr = null;
}
}
if (isset(Smarty::$global_tpl_vars[$variable])) {
// found it, return it
return Smarty::$global_tpl_vars[$variable];
}
if ($this->smarty->error_unassigned && $error_enable) {
// force a notice
$x = $$variable;
}
return new Undefined_Smarty_Variable;
}
/**
* gets a config variable
*
* @param string $variable the name of the config variable
* @param bool $error_enable
*
* @return mixed the value of the config variable
*/
public function getConfigVariable($variable, $error_enable = true)
{
$_ptr = $this;
while ($_ptr !== null) {
if (isset($_ptr->config_vars[$variable])) {
// found it, return it
return $_ptr->config_vars[$variable];
}
// not found, try at parent
$_ptr = $_ptr->parent;
}
if ($this->smarty->error_unassigned && $error_enable) {
// force a notice
$x = $$variable;
}
return null;
}
/**
* gets a stream variable
*
* @param string $variable the stream of the variable
*
* @throws SmartyException
* @return mixed the value of the stream variable
*/
public function getStreamVariable($variable)
{
$_result = '';
$fp = fopen($variable, 'r+');
if ($fp) {
while (!feof($fp) && ($current_line = fgets($fp)) !== false) {
$_result .= $current_line;
}
fclose($fp);
return $_result;
}
if ($this->smarty->error_unassigned) {
throw new SmartyException('Undefined stream variable "' . $variable . '"');
} else {
return null;
}
}
/**
* Returns a single or all config variables
*
* @param string $varname variable name or null
* @param bool $search_parents
*
* @return string variable value or or array of variables
*/
public function getConfigVars($varname = null, $search_parents = true)
{
$_ptr = $this;
$var_array = array();
while ($_ptr !== null) {
if (isset($varname)) {
if (isset($_ptr->config_vars[$varname])) {
return $_ptr->config_vars[$varname];
}
} else {
$var_array = array_merge($_ptr->config_vars, $var_array);
}
// not found, try at parent
if ($search_parents) {
$_ptr = $_ptr->parent;
} else {
$_ptr = null;
}
}
if (isset($varname)) {
return '';
} else {
return $var_array;
}
}
/**
* Deassigns a single or all config variables
*
* @param string $varname variable name or null
*
* @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
*/
public function clearConfig($varname = null)
{
if (isset($varname)) {
unset($this->config_vars[$varname]);
} else {
$this->config_vars = array();
}
return $this;
}
}
/**
* class for the Smarty data object
* The Smarty data object will hold Smarty variables in the current scope
*
* @package Smarty
* @subpackage Template
*/
class Smarty_Data extends Smarty_Internal_Data
{
/**
* Smarty object
*
* @var Smarty
*/
public $smarty = null;
/**
* create Smarty data object
*
* @param Smarty|array $_parent parent template
* @param Smarty|Smarty_Internal_Template $smarty global smarty instance
* @param string $name unknown method-name
* @param array $args argument array
*
* @return mixed
* @throws SmartyException
*/
public function __construct($_parent = null, $smarty = null)
public function __call($name, $args)
{
$this->smarty = $smarty;
if (is_object($_parent)) {
// when object set up back pointer
$this->parent = $_parent;
} elseif (is_array($_parent)) {
// set up variable values
foreach ($_parent as $_key => $_val) {
$this->tpl_vars[$_key] = new Smarty_variable($_val);
}
} elseif ($_parent != null) {
throw new SmartyException("Wrong type for template variables");
}
}
}
/**
* class for the Smarty variable object
* This class defines the Smarty variable object
*
* @package Smarty
* @subpackage Template
*/
class Smarty_Variable
{
/**
* template variable
*
* @var mixed
*/
public $value = null;
/**
* if true any output of this variable will be not cached
*
* @var boolean
*/
public $nocache = false;
/**
* the scope the variable will have (local,parent or root)
*
* @var int
*/
public $scope = Smarty::SCOPE_LOCAL;
/**
* create Smarty variable object
*
* @param mixed $value the value to assign
* @param boolean $nocache if true any output of this variable will be not cached
* @param int $scope the scope the variable will have (local,parent or root)
*/
public function __construct($value = null, $nocache = false, $scope = Smarty::SCOPE_LOCAL)
{
$this->value = $value;
$this->nocache = $nocache;
$this->scope = $scope;
}
/**
* <<magic>> String conversion
*
* @return string
*/
public function __toString()
{
return (string) $this->value;
}
}
/**
* class for undefined variable object
* This class defines an object for undefined variable handling
*
* @package Smarty
* @subpackage Template
*/
class Undefined_Smarty_Variable
{
/**
* Returns FALSE for 'nocache' and NULL otherwise.
*
* @param string $name
*
* @return bool
*/
public function __get($name)
{
if ($name == 'nocache') {
return false;
} else {
return null;
}
}
/**
* Always returns an empty string.
*
* @return string
*/
public function __toString()
{
return "";
return $this->ext->_callExternalMethod($this, $name, $args);
}
}
+318 -142
View File
@@ -1,7 +1,7 @@
<?php
/**
* Smarty Internal Plugin Debug
* Class to collect data for the Smarty Debugging Consol
* Class to collect data for the Smarty Debugging Console
*
* @package Smarty
* @subpackage Debug
@@ -21,165 +21,245 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
*
* @var array
*/
public static $template_data = array();
public $template_data = array();
/**
* List of uid's which shall be ignored
*
* @var array
*/
public static $ignore_uid = array();
public $ignore_uid = array();
/**
* Ignore template
* Index of display() and fetch() calls
*
* @param object $template
* @var int
*/
public static function ignore($template)
public $index = 0;
/**
* Counter for window offset
*
* @var int
*/
public $offset = 0;
/**
* Start logging template
*
* @param \Smarty_Internal_Template $template template
* @param null $mode true: display false: fetch null: subtemplate
*/
public function start_template(Smarty_Internal_Template $template, $mode = null)
{
// calculate Uid if not already done
if ($template->source->uid == '') {
$template->source->filepath;
if (isset($mode)) {
$this->index ++;
$this->offset ++;
$this->template_data[$this->index] = null;
}
self::$ignore_uid[$template->source->uid] = true;
}
/**
* Start logging of compile time
*
* @param object $template
*/
public static function start_compile($template)
{
static $_is_stringy = array('string' => true, 'eval' => true);
if (!empty($template->compiler->trace_uid)) {
$key = $template->compiler->trace_uid;
if (!isset(self::$template_data[$key])) {
if (isset($_is_stringy[$template->source->type])) {
self::$template_data[$key]['name'] = '\'' . substr($template->source->name, 0, 25) . '...\'';
} else {
self::$template_data[$key]['name'] = $template->source->filepath;
}
self::$template_data[$key]['compile_time'] = 0;
self::$template_data[$key]['render_time'] = 0;
self::$template_data[$key]['cache_time'] = 0;
}
} else {
if (isset(self::$ignore_uid[$template->source->uid])) {
return;
}
$key = self::get_key($template);
}
self::$template_data[$key]['start_time'] = microtime(true);
}
/**
* End logging of compile time
*
* @param object $template
*/
public static function end_compile($template)
{
if (!empty($template->compiler->trace_uid)) {
$key = $template->compiler->trace_uid;
} else {
if (isset(self::$ignore_uid[$template->source->uid])) {
return;
}
$key = self::get_key($template);
}
self::$template_data[$key]['compile_time'] += microtime(true) - self::$template_data[$key]['start_time'];
}
/**
* Start logging of render time
*
* @param object $template
*/
public static function start_render($template)
{
$key = self::get_key($template);
self::$template_data[$key]['start_time'] = microtime(true);
}
/**
* End logging of compile time
*
* @param object $template
*/
public static function end_render($template)
{
$key = self::get_key($template);
self::$template_data[$key]['render_time'] += microtime(true) - self::$template_data[$key]['start_time'];
}
/**
* Start logging of cache time
*
* @param object $template cached template
*/
public static function start_cache($template)
{
$key = self::get_key($template);
self::$template_data[$key]['start_time'] = microtime(true);
$key = $this->get_key($template);
$this->template_data[$this->index][$key]['start_template_time'] = microtime(true);
}
/**
* End logging of cache time
*
* @param object $template cached template
* @param \Smarty_Internal_Template $template cached template
*/
public static function end_cache($template)
public function end_template(Smarty_Internal_Template $template)
{
$key = self::get_key($template);
self::$template_data[$key]['cache_time'] += microtime(true) - self::$template_data[$key]['start_time'];
$key = $this->get_key($template);
$this->template_data[$this->index][$key]['total_time'] +=
microtime(true) - $this->template_data[$this->index][$key]['start_template_time'];
//$this->template_data[$this->index][$key]['properties'] = $template->properties;
}
/**
* Opens a window for the Smarty Debugging Consol and display the data
* Start logging of compile time
*
* @param \Smarty_Internal_Template $template
*/
public function start_compile(Smarty_Internal_Template $template)
{
static $_is_stringy = array('string' => true, 'eval' => true);
if (!empty($template->compiler->trace_uid)) {
$key = $template->compiler->trace_uid;
if (!isset($this->template_data[$this->index][$key])) {
if (isset($_is_stringy[$template->source->type])) {
$this->template_data[$this->index][$key]['name'] =
'\'' . substr($template->source->name, 0, 25) . '...\'';
} else {
$this->template_data[$this->index][$key]['name'] = $template->source->filepath;
}
$this->template_data[$this->index][$key]['compile_time'] = 0;
$this->template_data[$this->index][$key]['render_time'] = 0;
$this->template_data[$this->index][$key]['cache_time'] = 0;
}
} else {
if (isset($this->ignore_uid[$template->source->uid])) {
return;
}
$key = $this->get_key($template);
}
$this->template_data[$this->index][$key]['start_time'] = microtime(true);
}
/**
* End logging of compile time
*
* @param \Smarty_Internal_Template $template
*/
public function end_compile(Smarty_Internal_Template $template)
{
if (!empty($template->compiler->trace_uid)) {
$key = $template->compiler->trace_uid;
} else {
if (isset($this->ignore_uid[$template->source->uid])) {
return;
}
$key = $this->get_key($template);
}
$this->template_data[$this->index][$key]['compile_time'] +=
microtime(true) - $this->template_data[$this->index][$key]['start_time'];
}
/**
* Start logging of render time
*
* @param \Smarty_Internal_Template $template
*/
public function start_render(Smarty_Internal_Template $template)
{
$key = $this->get_key($template);
$this->template_data[$this->index][$key]['start_time'] = microtime(true);
}
/**
* End logging of compile time
*
* @param \Smarty_Internal_Template $template
*/
public function end_render(Smarty_Internal_Template $template)
{
$key = $this->get_key($template);
$this->template_data[$this->index][$key]['render_time'] +=
microtime(true) - $this->template_data[$this->index][$key]['start_time'];
}
/**
* Start logging of cache time
*
* @param \Smarty_Internal_Template $template cached template
*/
public function start_cache(Smarty_Internal_Template $template)
{
$key = $this->get_key($template);
$this->template_data[$this->index][$key]['start_time'] = microtime(true);
}
/**
* End logging of cache time
*
* @param \Smarty_Internal_Template $template cached template
*/
public function end_cache(Smarty_Internal_Template $template)
{
$key = $this->get_key($template);
$this->template_data[$this->index][$key]['cache_time'] +=
microtime(true) - $this->template_data[$this->index][$key]['start_time'];
}
/**
* Register template object
*
* @param \Smarty_Internal_Template $template cached template
*/
public function register_template(Smarty_Internal_Template $template)
{
}
/**
* Register data object
*
* @param \Smarty_Data $data data object
*/
public static function register_data(Smarty_Data $data)
{
}
/**
* Opens a window for the Smarty Debugging Console and display the data
*
* @param Smarty_Internal_Template|Smarty $obj object to debug
* @param bool $full
*/
public static function display_debug($obj)
public function display_debug($obj, $full = false)
{
// prepare information of assigned variables
$ptr = self::get_debug_vars($obj);
if ($obj instanceof Smarty) {
$smarty = clone $obj;
} else {
$smarty = clone $obj->smarty;
if (!$full) {
$this->offset ++;
$savedIndex = $this->index;
$this->index = 9999;
}
if ($obj->_objType == 1) {
$smarty = $obj;
} else {
$smarty = $obj->smarty;
}
// create fresh instance of smarty for displaying the debug console
// to avoid problems if the application did overload the Smarty class
$debObj = new Smarty();
// copy the working dirs from application
$debObj->setCompileDir($smarty->getCompileDir());
// init properties by hand as user may have edited the original Smarty class
$debObj->setPluginsDir(is_dir(__DIR__ . '/../plugins') ? __DIR__ . '/../plugins' : $smarty->getPluginsDir());
$debObj->force_compile = false;
$debObj->compile_check = true;
$debObj->left_delimiter = '{';
$debObj->right_delimiter = '}';
$debObj->security_policy = null;
$debObj->debugging = false;
$debObj->debugging_ctrl = 'NONE';
$debObj->error_reporting = E_ALL & ~E_NOTICE;
$debObj->debug_tpl = isset($smarty->debug_tpl) ? $smarty->debug_tpl : 'file:' . __DIR__ . '/../debug.tpl';
$debObj->registered_plugins = array();
$debObj->registered_resources = array();
$debObj->registered_filters = array();
$debObj->autoload_filters = array();
$debObj->default_modifiers = array();
$debObj->escape_html = true;
$debObj->caching = false;
$debObj->compile_id = null;
$debObj->cache_id = null;
// prepare information of assigned variables
$ptr = $this->get_debug_vars($obj);
$_assigned_vars = $ptr->tpl_vars;
ksort($_assigned_vars);
$_config_vars = $ptr->config_vars;
ksort($_config_vars);
$smarty->registered_filters = array();
$smarty->autoload_filters = array();
$smarty->default_modifiers = array();
$smarty->force_compile = false;
$smarty->left_delimiter = '{';
$smarty->right_delimiter = '}';
$smarty->debugging = false;
$smarty->debugging_ctrl = 'NONE';
$smarty->force_compile = false;
$_template = new Smarty_Internal_Template($smarty->debug_tpl, $smarty);
$_template->caching = false;
$_template->disableSecurity();
$_template->cache_id = null;
$_template->compile_id = null;
if ($obj instanceof Smarty_Internal_Template) {
$debugging = $smarty->debugging;
$_template = new Smarty_Internal_Template($debObj->debug_tpl, $debObj);
if ($obj->_objType == 2) {
$_template->assign('template_name', $obj->source->type . ':' . $obj->source->name);
}
if ($obj instanceof Smarty) {
$_template->assign('template_data', self::$template_data);
if ($obj->_objType == 1 || $full) {
$_template->assign('template_data', $this->template_data[$this->index]);
} else {
$_template->assign('template_data', null);
}
$_template->assign('assigned_vars', $_assigned_vars);
$_template->assign('config_vars', $_config_vars);
$_template->assign('execution_time', microtime(true) - $smarty->start_time);
$_template->assign('display_mode', $debugging == 2 || !$full);
$_template->assign('offset', $this->offset * 50);
echo $_template->fetch();
if (isset($full)) {
$this->index --;
}
if (!$full) {
$this->index = $savedIndex;
}
}
/**
@@ -189,31 +269,79 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
*
* @return StdClass
*/
public static function get_debug_vars($obj)
public function get_debug_vars($obj)
{
$config_vars = $obj->config_vars;
$config_vars = array();
foreach ($obj->config_vars as $key => $var) {
$config_vars[$key]['value'] = $var;
if ($obj->_objType == 2) {
$config_vars[$key]['scope'] = $obj->source->type . ':' . $obj->source->name;
} elseif ($obj->_objType == 4) {
$tpl_vars[$key]['scope'] = $obj->dataObjectName;
} else {
$config_vars[$key]['scope'] = 'Smarty object';
}
}
$tpl_vars = array();
foreach ($obj->tpl_vars as $key => $var) {
$tpl_vars[$key] = clone $var;
if ($obj instanceof Smarty_Internal_Template) {
$tpl_vars[$key]->scope = $obj->source->type . ':' . $obj->source->name;
} elseif ($obj instanceof Smarty_Data) {
$tpl_vars[$key]->scope = 'Data object';
foreach ($var as $varkey => $varvalue) {
if ($varkey == 'value') {
$tpl_vars[$key][$varkey] = $varvalue;
} else {
if ($varkey == 'nocache') {
if ($varvalue == true) {
$tpl_vars[$key][$varkey] = $varvalue;
}
} else {
if ($varkey != 'scope' || $varvalue !== 0) {
$tpl_vars[$key]['attributes'][$varkey] = $varvalue;
}
}
}
}
if ($obj->_objType == 2) {
$tpl_vars[$key]['scope'] = $obj->source->type . ':' . $obj->source->name;
} elseif ($obj->_objType == 4) {
$tpl_vars[$key]['scope'] = $obj->dataObjectName;
} else {
$tpl_vars[$key]->scope = 'Smarty root';
$tpl_vars[$key]['scope'] = 'Smarty object';
}
}
if (isset($obj->parent)) {
$parent = self::get_debug_vars($obj->parent);
$parent = $this->get_debug_vars($obj->parent);
foreach ($parent->tpl_vars as $name => $pvar) {
if (isset($tpl_vars[$name]) && $tpl_vars[$name]['value'] === $pvar['value']) {
$tpl_vars[$name]['scope'] = $pvar['scope'];
}
}
$tpl_vars = array_merge($parent->tpl_vars, $tpl_vars);
foreach ($parent->config_vars as $name => $pvar) {
if (isset($config_vars[$name]) && $config_vars[$name]['value'] === $pvar['value']) {
$config_vars[$name]['scope'] = $pvar['scope'];
}
}
$config_vars = array_merge($parent->config_vars, $config_vars);
} else {
foreach (Smarty::$global_tpl_vars as $name => $var) {
if (!array_key_exists($name, $tpl_vars)) {
$clone = clone $var;
$clone->scope = 'Global';
$tpl_vars[$name] = $clone;
foreach (Smarty::$global_tpl_vars as $key => $var) {
if (!array_key_exists($key, $tpl_vars)) {
foreach ($var as $varkey => $varvalue) {
if ($varkey == 'value') {
$tpl_vars[$key][$varkey] = $varvalue;
} else {
if ($varkey == 'nocache') {
if ($varvalue == true) {
$tpl_vars[$key][$varkey] = $varvalue;
}
} else {
if ($varkey != 'scope' || $varvalue !== 0) {
$tpl_vars[$key]['attributes'][$varkey] = $varvalue;
}
}
}
}
$tpl_vars[$key]['scope'] = 'Global';
}
}
}
@@ -224,11 +352,11 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
/**
* Return key into $template_data for template
*
* @param object $template template object
* @param \Smarty_Internal_Template $template template object
*
* @return string key into $template_data
*/
private static function get_key($template)
private function get_key(Smarty_Internal_Template $template)
{
static $_is_stringy = array('string' => true, 'eval' => true);
// calculate Uid if not already done
@@ -236,19 +364,67 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
$template->source->filepath;
}
$key = $template->source->uid;
if (isset(self::$template_data[$key])) {
if (isset($this->template_data[$this->index][$key])) {
return $key;
} else {
if (isset($_is_stringy[$template->source->type])) {
self::$template_data[$key]['name'] = '\'' . substr($template->source->name, 0, 25) . '...\'';
$this->template_data[$this->index][$key]['name'] =
'\'' . substr($template->source->name, 0, 25) . '...\'';
} else {
self::$template_data[$key]['name'] = $template->source->filepath;
$this->template_data[$this->index][$key]['name'] = $template->source->filepath;
}
self::$template_data[$key]['compile_time'] = 0;
self::$template_data[$key]['render_time'] = 0;
self::$template_data[$key]['cache_time'] = 0;
$this->template_data[$this->index][$key]['compile_time'] = 0;
$this->template_data[$this->index][$key]['render_time'] = 0;
$this->template_data[$this->index][$key]['cache_time'] = 0;
$this->template_data[$this->index][$key]['total_time'] = 0;
return $key;
}
}
/**
* Ignore template
*
* @param \Smarty_Internal_Template $template
*/
public function ignore(Smarty_Internal_Template $template)
{
// calculate Uid if not already done
if ($template->source->uid == '') {
$template->source->filepath;
}
$this->ignore_uid[$template->source->uid] = true;
}
/**
* handle 'URL' debugging mode
*
* @param Smarty $smarty
*/
public function debugUrl(Smarty $smarty)
{
if (isset($_SERVER['QUERY_STRING'])) {
$_query_string = $_SERVER['QUERY_STRING'];
} else {
$_query_string = '';
}
if (false !== strpos($_query_string, $smarty->smarty_debug_id)) {
if (false !== strpos($_query_string, $smarty->smarty_debug_id . '=on')) {
// enable debugging for this browser session
setcookie('SMARTY_DEBUG', true);
$smarty->debugging = true;
} elseif (false !== strpos($_query_string, $smarty->smarty_debug_id . '=off')) {
// disable debugging for this browser session
setcookie('SMARTY_DEBUG', false);
$smarty->debugging = false;
} else {
// enable debugging for this page
$smarty->debugging = true;
}
} else {
if (isset($_COOKIE['SMARTY_DEBUG'])) {
$smarty->debugging = true;
}
}
}
}
@@ -0,0 +1,134 @@
<?php
/**
* Smarty Extension Clear
*
* $smarty->clear() method file cache file resource
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Extension_Clear
{
/**
* Empty cache for a specific template
*
* @param Smarty $smarty
* @param string $resource_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer $exp_time expiration time (number of seconds, not timestamp)
*
* @return integer number of cache files deleted
*/
public static function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
{
$_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
$_compile_id = isset($compile_id) ? preg_replace('![^\w]+!', '_', $compile_id) : null;
$_dir_sep = $smarty->use_sub_dirs ? '/' : '^';
$_compile_id_offset = $smarty->use_sub_dirs ? 3 : 0;
$_dir = $smarty->getCacheDir();
if ($_dir == '/') { //We should never want to delete this!
return 0;
}
$_dir_length = strlen($_dir);
if (isset($_cache_id)) {
$_cache_id_parts = explode('|', $_cache_id);
$_cache_id_parts_count = count($_cache_id_parts);
if ($smarty->use_sub_dirs) {
foreach ($_cache_id_parts as $id_part) {
$_dir .= $id_part . DS;
}
}
}
if (isset($resource_name)) {
$_save_stat = $smarty->caching;
$smarty->caching = true;
$tpl = new $smarty->template_class($resource_name, $smarty);
$smarty->caching = $_save_stat;
// remove from template cache
$tpl->source; // have the template registered before unset()
if ($tpl->source->exists) {
$_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath));
} else {
return 0;
}
}
$_count = 0;
$_time = time();
if (file_exists($_dir)) {
$_cacheDirs = new RecursiveDirectoryIterator($_dir);
$_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($_cache as $_file) {
if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) {
continue;
}
// directory ?
if ($_file->isDir()) {
if (!$_cache->isDot()) {
// delete folder if empty
@rmdir($_file->getPathname());
}
} else {
$_parts = explode($_dir_sep, str_replace('\\', '/', substr((string) $_file, $_dir_length)));
$_parts_count = count($_parts);
// check name
if (isset($resource_name)) {
if ($_parts[$_parts_count - 1] != $_resourcename_parts) {
continue;
}
}
// check compile id
if (isset($_compile_id) && (!isset($_parts[$_parts_count - 2 - $_compile_id_offset]) ||
$_parts[$_parts_count - 2 - $_compile_id_offset] != $_compile_id)
) {
continue;
}
// check cache id
if (isset($_cache_id)) {
// count of cache id parts
$_parts_count = (isset($_compile_id)) ? $_parts_count - 2 - $_compile_id_offset :
$_parts_count - 1 - $_compile_id_offset;
if ($_parts_count < $_cache_id_parts_count) {
continue;
}
for ($i = 0; $i < $_cache_id_parts_count; $i ++) {
if ($_parts[$i] != $_cache_id_parts[$i]) {
continue 2;
}
}
}
// expired ?
if (isset($exp_time)) {
if ($exp_time < 0) {
preg_match('#\'cache_lifetime\' =>\s*(\d*)#', file_get_contents($_file), $match);
if ($_time < (@filemtime($_file) + $match[1])) {
continue;
}
} else {
if ($_time - @filemtime($_file) < $exp_time) {
continue;
}
}
}
// remove from template cache
if (isset($smarty->_cache['template_objects'])) {
foreach ($smarty->_cache['template_objects'] as $key => $tpl) {
if (isset($tpl->cached) && $tpl->cached->filepath == (string) $_file) {
unset($smarty->_cache['template_objects'][$key]);
}
}
}
$_count += @unlink((string) $_file) ? 1 : 0;
if (function_exists('opcache_invalidate')) {
opcache_invalidate((string) $_file);
}
}
}
}
return $_count;
}
}
@@ -0,0 +1,157 @@
<?php
/**
* Smarty Extension handler
*
* Load extensions dynamically
*
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*
* @property Smarty_Internal_Runtime_Inheritance $_inheritance
* @property Smarty_Internal_Runtime_SubTemplate $_subTemplate
* @property Smarty_Internal_Runtime_TplFunction $_tplFunction
* @property Smarty_Internal_Runtime_Var $_var
* @property Smarty_Internal_Runtime_Config $_config
* @property Smarty_Internal_Runtime_Foreach $_foreach
* @property Smarty_Internal_Runtime_Hhvm $_hhvm
* @property Smarty_Internal_Runtime_WriteFile $_writeFile
* @property Smarty_Internal_Runtime_ValidateCompiled $_validateCompiled
* @property Smarty_Internal_Runtime_CodeFrame $_codeFrame
* @property Smarty_Internal_Runtime_FilterHandler $_filterHandler
* @property Smarty_Internal_Runtime_GetIncludePath $_getIncludePath
* @property Smarty_Internal_Runtime_UpdateScope $_updateScope
* @property Smarty_Internal_Runtime_IsCached $_isCached
* @property Smarty_Internal_Runtime_CacheModify $_cacheModify
* @property Smarty_Internal_Runtime_UpdateCache $_updateCache
* @property Smarty_Internal_Method_GetTemplateVars $getTemplateVars
* @property Smarty_Internal_Method_Append $append
* @property Smarty_Internal_Method_AppendByRef $appendByRef
* @property Smarty_Internal_Method_AssignGlobal $assignGlobal
* @property Smarty_Internal_Method_AssignByRef $assignByRef
* @property Smarty_Internal_Method_LoadFilter $loadFilter
* @property Smarty_Internal_Method_LoadPlugin $loadPlugin
* @property Smarty_Internal_Method_RegisterFilter $registerFilter
* @property Smarty_Internal_Method_RegisterObject $registerObject
* @property Smarty_Internal_Method_RegisterPlugin $registerPlugin
*/
class Smarty_Internal_Extension_Handler
{
public $objType = null;
/**
* Cache for property information from generic getter/setter
* Preloaded with names which should not use with generic getter/setter
*
* @var array
*/
private $_property_info = array('AutoloadFilters' => 0, 'DefaultModifiers' => 0, 'ConfigVars' => 0,
'DebugTemplate' => 0, 'RegisteredObject' => 0, 'StreamVariable' => 0,
'TemplateVars' => 0,);#
private $resolvedProperties = array();
/**
* Call external Method
*
* @param \Smarty_Internal_Data $data
* @param string $name external method names
* @param array $args argument array
*
* @return mixed
* @throws SmartyException
*/
public function _callExternalMethod(Smarty_Internal_Data $data, $name, $args)
{
/* @var Smarty $data ->smarty */
$smarty = isset($data->smarty) ? $data->smarty : $data;
if (!isset($smarty->ext->$name)) {
$class = 'Smarty_Internal_Method_' . ucfirst($name);
if (preg_match('/^(set|get)([A-Z].*)$/', $name, $match)) {
if (!isset($this->_property_info[$prop = $match[2]])) {
// convert camel case to underscored name
$this->resolvedProperties[$prop] = $pn = strtolower(join('_',
preg_split('/([A-Z][^A-Z]*)/', $prop, - 1,
PREG_SPLIT_NO_EMPTY |
PREG_SPLIT_DELIM_CAPTURE)));
$this->_property_info[$prop] = property_exists($data, $pn) ? 1 :
($data->_objType == 2 && property_exists($smarty, $pn) ? 2 : 0);
}
if ($this->_property_info[$prop]) {
$pn = $this->resolvedProperties[$prop];
if ($match[1] == 'get') {
return $this->_property_info[$prop] == 1 ? $data->$pn : $data->smarty->$pn;
} else {
return $this->_property_info[$prop] == 1 ? $data->$pn = $args[0] :
$data->smarty->$pn = $args[0];
}
} elseif (!class_exists($class)) {
throw new SmartyException("property '$pn' does not exist.");
}
}
if (class_exists($class)) {
$callback = array($smarty->ext->$name = new $class(), $name);
}
} else {
$callback = array($smarty->ext->$name, $name);
}
array_unshift($args, $data);
if (isset($callback) && $callback[0]->objMap | $data->_objType) {
return call_user_func_array($callback, $args);
}
return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), $args);
}
/**
* set extension property
*
* @param string $property_name property name
* @param mixed $value value
*
* @throws SmartyException
*/
public function __set($property_name, $value)
{
$this->$property_name = $value;
}
/**
* get extension object
*
* @param string $property_name property name
*
* @return mixed|Smarty_Template_Cached
* @throws SmartyException
*/
public function __get($property_name)
{
// object properties of runtime template extensions will start with '_'
if ($property_name[0] == '_') {
$class = 'Smarty_Internal_Runtime_' . ucfirst(substr($property_name, 1));
} else {
$class = 'Smarty_Internal_Method_' . ucfirst($property_name);
}
if (class_exists($class)) {
return $this->$property_name = new $class();
}
return $this;
}
/**
* Call error handler for undefined method
*
* @param string $name unknown method-name
* @param array $args argument array
*
* @return mixed
* @throws SmartyException
*/
public function __call($name, $args)
{
return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), $args);
}
}
@@ -1,52 +0,0 @@
<?php
/**
* Smarty Internal Plugin Function Call Handler
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
/**
* This class does call function defined with the {function} tag
*
* @package Smarty
* @subpackage PluginsInternal
*/
class Smarty_Internal_Function_Call_Handler
{
/**
* This function handles calls to template functions defined by {function}
* It does create a PHP function at the first call
*
* @param string $_name template function name
* @param Smarty_Internal_Template $_template template object
* @param array $_params Smarty variables passed as call parameter
* @param string $_hash nocache hash value
* @param bool $_nocache nocache flag
*/
public static function call($_name, Smarty_Internal_Template $_template, $_params, $_hash, $_nocache)
{
if ($_nocache) {
$_function = "smarty_template_function_{$_name}_nocache";
} else {
$_function = "smarty_template_function_{$_hash}_{$_name}";
}
if (!is_callable($_function)) {
$_code = "function {$_function}(\$_smarty_tpl,\$params) {
\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
foreach (\$_smarty_tpl->smarty->template_functions['{$_name}']['parameter'] as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);};
foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
if ($_nocache) {
$_code .= preg_replace(array("!<\?php echo \\'/\*%%SmartyNocache:{$_template->smarty->template_functions[$_name]['nocache_hash']}%%\*/|/\*/%%SmartyNocache:{$_template->smarty->template_functions[$_name]['nocache_hash']}%%\*/\\';\?>!",
"!\\\'!"), array('', "'"), $_template->smarty->template_functions[$_name]['compiled']);
$_template->smarty->template_functions[$_name]['called_nocache'] = true;
} else {
$_code .= preg_replace("/{$_template->smarty->template_functions[$_name]['nocache_hash']}/", $_template->properties['nocache_hash'], $_template->smarty->template_functions[$_name]['compiled']);
}
$_code .= "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;}";
eval($_code);
}
$_function($_template, $_params);
}
}
@@ -1,46 +0,0 @@
<?php
/**
* Smarty read include path plugin
*
* @package Smarty
* @subpackage PluginsInternal
* @author Monte Ohrt
*/
/**
* Smarty Internal Read Include Path Class
*
* @package Smarty
* @subpackage PluginsInternal
*/
class Smarty_Internal_Get_Include_Path
{
/**
* Return full file path from PHP include_path
*
* @param string $filepath filepath
*
* @return string|boolean full filepath or false
*/
public static function getIncludePath($filepath)
{
static $_include_path = null;
if (function_exists('stream_resolve_include_path')) {
// available since PHP 5.3.2
return stream_resolve_include_path($filepath);
}
if ($_include_path === null) {
$_include_path = explode(PATH_SEPARATOR, get_include_path());
}
foreach ($_include_path as $_path) {
if (file_exists($_path . DS . $filepath)) {
return $_path . DS . $filepath;
}
}
return false;
}
}
@@ -0,0 +1,51 @@
<?php
/**
* Smarty Method AddAutoloadFilters
*
* Smarty::addAutoloadFilters() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_AddAutoloadFilters extends Smarty_Internal_Method_SetAutoloadFilters
{
/**
* Add autoload filters
*
* @api Smarty::setAutoloadFilters()
*
* @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
* @param array $filters filters to load automatically
* @param string $type "pre", "output", … specify the
* filter type to set. Defaults to
* none treating $filters' keys as
* the appropriate types
*
* @return \Smarty|\Smarty_Internal_Template
*/
public function addAutoloadFilters(Smarty_Internal_TemplateBase $obj, $filters, $type = null)
{
$smarty = isset($obj->smarty) ? $obj->smarty : $obj;
if ($type !== null) {
$this->_checkFilterType($type);
if (!empty($smarty->autoload_filters[$type])) {
$smarty->autoload_filters[$type] = array_merge($smarty->autoload_filters[$type], (array) $filters);
} else {
$smarty->autoload_filters[$type] = (array) $filters;
}
} else {
foreach ((array) $filters as $type => $value) {
$this->_checkFilterType($type);
if (!empty($smarty->autoload_filters[$type])) {
$smarty->autoload_filters[$type] = array_merge($smarty->autoload_filters[$type], (array) $value);
} else {
$smarty->autoload_filters[$type] = (array) $value;
}
}
}
return $obj;
}
}
@@ -0,0 +1,42 @@
<?php
/**
* Smarty Method AddDefaultModifiers
*
* Smarty::addDefaultModifiers() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_AddDefaultModifiers
{
/**
* Valid for Smarty and template object
*
* @var int
*/
public $objMap = 3;
/**
* Add default modifiers
*
* @api Smarty::addDefaultModifiers()
*
* @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
* @param array|string $modifiers modifier or list of modifiers
* to add
*
* @return \Smarty|\Smarty_Internal_Template
*/
public function addDefaultModifiers(Smarty_Internal_TemplateBase $obj, $modifiers)
{
$smarty = isset($obj->smarty) ? $obj->smarty : $obj;
if (is_array($modifiers)) {
$this->default_modifiers = array_merge($smarty->default_modifiers, $modifiers);
} else {
$smarty->default_modifiers[] = $modifiers;
}
return $obj;
}
}
@@ -0,0 +1,74 @@
<?php
/**
* Smarty Method Append
*
* Smarty::append() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_Append
{
/**
* Valid for all objects
*
* @var int
*/
public $objMap = 7;
/**
* appends values to template variables
*
* @api Smarty::append()
* @link http://www.smarty.net/docs/en/api.append.tpl
*
* @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
* @param array|string $tpl_var the template variable name(s)
* @param mixed $value the value to append
* @param bool $merge flag if array elements shall be merged
* @param bool $nocache if true any output of this variable will
* be not cached
*
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public function append(Smarty_Internal_Data $data, $tpl_var, $value = null, $merge = false, $nocache = false)
{
if (is_array($tpl_var)) {
// $tpl_var is an array, ignore $value
foreach ($tpl_var as $_key => $_val) {
if ($_key != '') {
$this->append($data, $_key, $_val, $merge, $nocache);
}
}
} else {
if ($tpl_var != '' && isset($value)) {
if (!isset($data->tpl_vars[$tpl_var])) {
$tpl_var_inst = $data->ext->getTemplateVars->_getVariable($data, $tpl_var, null, true, false);
if ($tpl_var_inst instanceof Smarty_Undefined_Variable) {
$data->tpl_vars[$tpl_var] = new Smarty_Variable(null, $nocache);
} else {
$data->tpl_vars[$tpl_var] = clone $tpl_var_inst;
}
}
if (!(is_array($data->tpl_vars[$tpl_var]->value) ||
$data->tpl_vars[$tpl_var]->value instanceof ArrayAccess)
) {
settype($data->tpl_vars[$tpl_var]->value, 'array');
}
if ($merge && is_array($value)) {
foreach ($value as $_mkey => $_mval) {
$data->tpl_vars[$tpl_var]->value[$_mkey] = $_mval;
}
} else {
$data->tpl_vars[$tpl_var]->value[] = $value;
}
}
if ($data->_objType == 2 && $data->scope) {
$data->ext->_updateScope->updateScope($data, $tpl_var);
}
}
return $data;
}
}
@@ -0,0 +1,50 @@
<?php
/**
* Smarty Method AppendByRef
*
* Smarty::appendByRef() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_AppendByRef
{
/**
* appends values to template variables by reference
*
* @api Smarty::appendByRef()
* @link http://www.smarty.net/docs/en/api.append.by.ref.tpl
*
* @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
* @param string $tpl_var the template variable name
* @param mixed &$value the referenced value to append
* @param bool $merge flag if array elements shall be merged
*
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public static function appendByRef(Smarty_Internal_Data $data, $tpl_var, &$value, $merge = false)
{
if ($tpl_var != '' && isset($value)) {
if (!isset($data->tpl_vars[$tpl_var])) {
$data->tpl_vars[$tpl_var] = new Smarty_Variable();
}
if (!is_array($data->tpl_vars[$tpl_var]->value)) {
settype($data->tpl_vars[$tpl_var]->value, 'array');
}
if ($merge && is_array($value)) {
foreach ($value as $_key => $_val) {
$data->tpl_vars[$tpl_var]->value[$_key] = &$value[$_key];
}
} else {
$data->tpl_vars[$tpl_var]->value[] = &$value;
}
if ($data->_objType == 2 && $data->scope) {
$data->ext->_updateScope->updateScope($data, $tpl_var);
}
}
return $data;
}
}
@@ -0,0 +1,36 @@
<?php
/**
* Smarty Method AssignByRef
*
* Smarty::assignByRef() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_AssignByRef
{
/**
* assigns values to template variables by reference
*
* @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
* @param string $tpl_var the template variable name
* @param $value
* @param boolean $nocache if true any output of this variable will be not cached
*
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public function assignByRef(Smarty_Internal_Data $data, $tpl_var, &$value, $nocache)
{
if ($tpl_var != '') {
$data->tpl_vars[$tpl_var] = new Smarty_Variable(null, $nocache);
$data->tpl_vars[$tpl_var]->value = &$value;
if ($data->_objType == 2 && $data->scope) {
$data->ext->_updateScope->updateScope($data, $tpl_var);
}
}
return $data;
}
}
@@ -0,0 +1,43 @@
<?php
/**
* Smarty Method AssignGlobal
*
* Smarty::assignGlobal() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_AssignGlobal
{
/**
* Valid for all objects
*
* @var int
*/
public $objMap = 7;
/**
* assigns a global Smarty variable
*
* @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
* @param string $varName the global variable name
* @param mixed $value the value to assign
* @param boolean $nocache if true any output of this variable will be not cached
*
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public function assignGlobal(Smarty_Internal_Data $data, $varName, $value = null, $nocache = false)
{
if ($varName != '') {
Smarty::$global_tpl_vars[$varName] = new Smarty_Variable($value, $nocache);
$ptr = $data;
while ($ptr->_objType == 2) {
$ptr->tpl_vars[$varName] = clone Smarty::$global_tpl_vars[$varName];
$ptr = $ptr->parent;
}
}
return $data;
}
}
@@ -0,0 +1,37 @@
<?php
/**
* Smarty Method ClearAllAssign
*
* Smarty::clearAllAssign() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_ClearAllAssign
{
/**
* Valid for all objects
*
* @var int
*/
public $objMap = 7;
/**
* clear all the assigned template variables.
*
* @api Smarty::clearAllAssign()
* @link http://www.smarty.net/docs/en/api.clear.all.assign.tpl
*
* @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
*
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public function clearAllAssign(Smarty_Internal_Data $data)
{
$data->tpl_vars = array();
return $data;
}
}
@@ -0,0 +1,43 @@
<?php
/**
* Smarty Method ClearAllCache
*
* Smarty::clearAllCache() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_ClearAllCache
{
/**
* Valid for Smarty object
*
* @var int
*/
public $objMap = 1;
/**
* Empty cache folder
*
* @api Smarty::clearAllCache()
* @link http://www.smarty.net/docs/en/api.clear.all.cache.tpl
*
* @param \Smarty $smarty
* @param integer $exp_time expiration time
* @param string $type resource type
*
* @return integer number of cache files deleted
*/
public function clearAllCache(Smarty $smarty, $exp_time = null, $type = null)
{
// load cache resource and call clearAll
$_cache_resource = Smarty_CacheResource::load($smarty, $type);
if ($smarty->caching_type != 'file') {
$_cache_resource->invalidLoadedCache($smarty);
}
return $_cache_resource->clearAll($smarty, $exp_time);
}
}
@@ -0,0 +1,44 @@
<?php
/**
* Smarty Method ClearAssign
*
* Smarty::clearAssign() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_ClearAssign
{
/**
* Valid for all objects
*
* @var int
*/
public $objMap = 7;
/**
* clear the given assigned template variable(s).
*
* @api Smarty::clearAssign()
* @link http://www.smarty.net/docs/en/api.clear.assign.tpl
*
* @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
* @param string|array $tpl_var the template variable(s) to clear
*
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public function clearAssign(Smarty_Internal_Data $data, $tpl_var)
{
if (is_array($tpl_var)) {
foreach ($tpl_var as $curr_var) {
unset($data->tpl_vars[$curr_var]);
}
} else {
unset($data->tpl_vars[$tpl_var]);
}
return $data;
}
}
@@ -0,0 +1,46 @@
<?php
/**
* Smarty Method ClearCache
*
* Smarty::clearCache() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_ClearCache
{
/**
* Valid for Smarty object
*
* @var int
*/
public $objMap = 1;
/**
* Empty cache for a specific template
*
* @api Smarty::clearCache()
* @link http://www.smarty.net/docs/en/api.clear.cache.tpl
*
* @param \Smarty $smarty
* @param string $template_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer $exp_time expiration time
* @param string $type resource type
*
* @return integer number of cache files deleted
*/
public function clearCache(Smarty $smarty, $template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
{
// load cache resource and call clear
$_cache_resource = Smarty_CacheResource::load($smarty, $type);
if ($smarty->caching_type != 'file' && !isset($template_name)) {
$_cache_resource->invalidLoadedCache($smarty);
}
return $_cache_resource->clear($smarty, $template_name, $cache_id, $compile_id, $exp_time);
}
}
@@ -0,0 +1,132 @@
<?php
/**
* Smarty Method ClearCompiledTemplate
*
* Smarty::clearCompiledTemplate() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_ClearCompiledTemplate
{
/**
* Valid for Smarty object
*
* @var int
*/
public $objMap = 1;
/**
* Delete compiled template file
*
* @api Smarty::clearCompiledTemplate()
* @link http://www.smarty.net/docs/en/api.clear.compiled.template.tpl
*
* @param \Smarty $smarty
* @param string $resource_name template name
* @param string $compile_id compile id
* @param integer $exp_time expiration time
*
* @return integer number of template files deleted
*/
public function clearCompiledTemplate(Smarty $smarty, $resource_name = null, $compile_id = null, $exp_time = null)
{
$_compile_dir = $smarty->getCompileDir();
if ($_compile_dir == '/') { //We should never want to delete this!
return 0;
}
$_compile_id = isset($compile_id) ? preg_replace('![^\w]+!', '_', $compile_id) : null;
$_dir_sep = $smarty->use_sub_dirs ? DS : '^';
if (isset($resource_name)) {
$_save_stat = $smarty->caching;
$smarty->caching = false;
/* @var Smarty_Internal_Template $tpl */
$tpl = new $smarty->template_class($resource_name, $smarty);
$smarty->caching = $_save_stat;
if ($tpl->source->exists) {
// remove from compileds cache
$tpl->source->compileds = array();
$_resource_part_1 = basename(str_replace('^', DS, $tpl->compiled->filepath));
$_resource_part_1_length = strlen($_resource_part_1);
} else {
return 0;
}
$_resource_part_2 = str_replace('.php', '.cache.php', $_resource_part_1);
$_resource_part_2_length = strlen($_resource_part_2);
}
$_dir = $_compile_dir;
if ($smarty->use_sub_dirs && isset($_compile_id)) {
$_dir .= $_compile_id . $_dir_sep;
}
if (isset($_compile_id)) {
$_compile_id_part = $_compile_dir . $_compile_id . $_dir_sep;
$_compile_id_part_length = strlen($_compile_id_part);
}
$_count = 0;
try {
$_compileDirs = new RecursiveDirectoryIterator($_dir);
// NOTE: UnexpectedValueException thrown for PHP >= 5.3
}
catch (Exception $e) {
return 0;
}
$_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($_compile as $_file) {
if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) {
continue;
}
$_filepath = (string) $_file;
if ($_file->isDir()) {
if (!$_compile->isDot()) {
// delete folder if empty
@rmdir($_file->getPathname());
}
} else {
$unlink = false;
if ((!isset($_compile_id) || (isset($_filepath[$_compile_id_part_length]) &&
$a = !strncmp($_filepath, $_compile_id_part, $_compile_id_part_length))) &&
(!isset($resource_name) || (isset($_filepath[$_resource_part_1_length]) &&
substr_compare($_filepath, $_resource_part_1, - $_resource_part_1_length,
$_resource_part_1_length) == 0) ||
(isset($_filepath[$_resource_part_2_length]) &&
substr_compare($_filepath, $_resource_part_2, - $_resource_part_2_length,
$_resource_part_2_length) == 0))
) {
if (isset($exp_time)) {
if (time() - @filemtime($_filepath) >= $exp_time) {
$unlink = true;
}
} else {
$unlink = true;
}
}
if ($unlink && @unlink($_filepath)) {
if (isset($smarty->_cache['template_objects'])) {
foreach ($smarty->_cache['template_objects'] as $key => $tpl) {
if (isset($tpl->compiled) && $tpl->compiled->filepath == $_filepath) {
unset($smarty->_cache['template_objects'][$key]);
}
}
}
$_count ++;
if (function_exists('opcache_invalidate')) {
opcache_invalidate($_filepath);
}
}
}
}
// clear compiled cache
if (!isset($resource_name) && isset($smarty->_cache['source_objects'])) {
foreach ($smarty->_cache['source_objects'] as $source) {
$source->compileds = array();
}
}
return $_count;
}
}
@@ -0,0 +1,41 @@
<?php
/**
* Smarty Method ClearConfig
*
* Smarty::clearConfig() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_ClearConfig
{
/**
* Valid for all objects
*
* @var int
*/
public $objMap = 7;
/**
* clear a single or all config variables
*
* @api Smarty::clearConfig()
* @link http://www.smarty.net/docs/en/api.clear.config.tpl
*
* @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
* @param string|null $name variable name or null
*
* @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty
*/
public function clearConfig(Smarty_Internal_Data $data, $name = null)
{
if (isset($name)) {
unset($data->config_vars[$name]);
} else {
$data->config_vars = array();
}
return $data;
}
}
@@ -0,0 +1,32 @@
<?php
/**
* Smarty Method CompileAllConfig
*
* Smarty::compileAllConfig() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_CompileAllConfig extends Smarty_Internal_Method_CompileAllTemplates
{
/**
* Compile all config files
*
* @api Smarty::compileAllConfig()
*
* @param \Smarty $smarty
* @param string $extension file extension
* @param bool $force_compile force all to recompile
* @param int $time_limit
* @param int $max_errors
*
* @return integer number of template files recompiled
*/
public function compileAllConfig(Smarty $smarty, $extension = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null)
{
return $this->compileAll($smarty, $extension, $force_compile, $time_limit, $max_errors, true);
}
}
@@ -0,0 +1,111 @@
<?php
/**
* Smarty Method CompileAllTemplates
*
* Smarty::compileAllTemplates() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_CompileAllTemplates
{
/**
* Valid for Smarty object
*
* @var int
*/
public $objMap = 1;
/**
* Compile all template files
*
* @api Smarty::compileAllTemplates()
*
* @param \Smarty $smarty
* @param string $extension file extension
* @param bool $force_compile force all to recompile
* @param int $time_limit
* @param int $max_errors
*
* @return integer number of template files recompiled
*/
public function compileAllTemplates(Smarty $smarty, $extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
{
return $this->compileAll($smarty, $extension, $force_compile, $time_limit, $max_errors);
}
/**
* Compile all template or config files
*
* @param \Smarty $smarty
* @param string $extension template file name extension
* @param bool $force_compile force all to recompile
* @param int $time_limit set maximum execution time
* @param int $max_errors set maximum allowed errors
* @param bool $isConfig flag true if called for config files
*
* @return int number of template files compiled
*/
protected function compileAll(Smarty $smarty, $extension, $force_compile, $time_limit, $max_errors, $isConfig = false)
{
// switch off time limit
if (function_exists('set_time_limit')) {
@set_time_limit($time_limit);
}
$_count = 0;
$_error_count = 0;
$sourceDir = $isConfig ? $smarty->getConfigDir() : $smarty->getTemplateDir();
// loop over array of source directories
foreach ($sourceDir as $_dir) {
$_dir_1 = new RecursiveDirectoryIterator($_dir);
$_dir_2 = new RecursiveIteratorIterator($_dir_1);
foreach ($_dir_2 as $_fileinfo) {
$_file = $_fileinfo->getFilename();
if (substr(basename($_fileinfo->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) {
continue;
}
if (!substr_compare($_file, $extension, - strlen($extension)) == 0) {
continue;
}
if ($_fileinfo->getPath() == !substr($_dir, 0, - 1)) {
$_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file;
}
echo "\n<br>", $_dir, '---', $_file;
flush();
$_start_time = microtime(true);
$_smarty = clone $smarty;
$_smarty->force_compile = $force_compile;
try {
/* @var Smarty_Internal_Template $_tpl */
$_tpl = new $smarty->template_class($_file, $_smarty);
$_tpl->caching = Smarty::CACHING_OFF;
$_tpl->source = $isConfig ? Smarty_Template_Config::load($_tpl) : Smarty_Template_Source::load($_tpl);
if ($_tpl->mustCompile()) {
$_tpl->compileTemplateSource();
$_count ++;
echo ' compiled in ', microtime(true) - $_start_time, ' seconds';
flush();
} else {
echo ' is up to date';
flush();
}
}
catch (Exception $e) {
echo "\n<br> ------>Error: ", $e->getMessage(), "<br><br>\n";
$_error_count ++;
}
// free memory
unset($_tpl);
$_smarty->_cache['template_objects'] = array();
if ($max_errors !== null && $_error_count == $max_errors) {
echo "\n<br><br>too many errors\n";
exit();
}
}
}
echo "\n<br>";
return $_count;
}
}
@@ -0,0 +1,182 @@
<?php
/**
* Smarty Method ConfigLoad
*
* Smarty::configLoad() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_ConfigLoad
{
/**
* Valid for all objects
*
* @var int
*/
public $objMap = 7;
/**
* load a config file, optionally load just selected sections
*
* @api Smarty::configLoad()
* @link http://www.smarty.net/docs/en/api.config.load.tpl
*
* @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
* @param string $config_file filename
* @param mixed $sections array of section names, single
* section or null
*
* @return \Smarty|\Smarty_Internal_Data|\Smarty_Internal_Template
* @throws \SmartyException
*/
public function configLoad(Smarty_Internal_Data $data, $config_file, $sections = null)
{
$this->_loadConfigFile($data, $config_file, $sections, 0);
return $data;
}
/**
* load a config file, optionally load just selected sections
*
* @api Smarty::configLoad()
* @link http://www.smarty.net/docs/en/api.config.load.tpl
*
* @param \Smarty|\Smarty_Internal_Data|\Smarty_Internal_Template $data
* @param string $config_file filename
* @param mixed $sections array of section names, single
* section or null
* @param int $scope scope into which config variables
* shall be loaded
*
* @return \Smarty|\Smarty_Internal_Data|\Smarty_Internal_Template
* @throws \SmartyException
*/
public function _loadConfigFile(Smarty_Internal_Data $data, $config_file, $sections = null, $scope = 0)
{
/* @var \Smarty $smarty */
$smarty = isset($data->smarty) ? $data->smarty : $data;
/* @var \Smarty_Internal_Template $confObj */
$confObj = new Smarty_Internal_Template($config_file, $smarty, $data);
$confObj->caching = Smarty::CACHING_OFF;
$confObj->source = Smarty_Template_Config::load($confObj);
$confObj->source->config_sections = $sections;
$confObj->source->scope = $scope;
$confObj->compiled = Smarty_Template_Compiled::load($confObj);
$confObj->compiled->render($confObj);
if ($data->_objType == 2) {
$data->compiled->file_dependency[$confObj->source->uid] =
array($confObj->source->filepath, $confObj->source->getTimeStamp(), $confObj->source->type);
}
}
/**
* load config variables into template object
*
* @param \Smarty_Internal_Template $tpl
* @param array $_config_vars
*
*/
public function _loadConfigVars(Smarty_Internal_Template $tpl, $_config_vars)
{
$this->_assignConfigVars($tpl->parent, $tpl, $_config_vars);
$scope = $tpl->source->scope;
if (!$scope && !$tpl->scope) {
return;
}
foreach (array($scope, $tpl->scope) as $s) {
$s = ($bubble_up = $s >= Smarty::SCOPE_BUBBLE_UP) ? $s - Smarty::SCOPE_BUBBLE_UP : $s;
if ($bubble_up && $s) {
$ptr = $tpl->parent->parent;
if (isset($ptr)) {
$this->_assignConfigVars($ptr, $tpl, $_config_vars);
$ptr = $ptr->parent;
}
if ($s == Smarty::SCOPE_PARENT) {
continue;
}
while (isset($ptr) && $ptr->_objType == 2) {
$this->_assignConfigVars($ptr, $tpl, $_config_vars);
$ptr = $ptr->parent;
}
if ($s == Smarty::SCOPE_TPL_ROOT) {
continue;
} elseif ($s == Smarty::SCOPE_SMARTY) {
$this->_assignConfigVars($tpl->smarty, $tpl, $_config_vars);
} elseif ($s == Smarty::SCOPE_GLOBAL) {
$this->_assignConfigVars($tpl->smarty, $tpl, $_config_vars);
} elseif ($s == Smarty::SCOPE_ROOT) {
while (isset($ptr->parent)) {
$ptr = $ptr->parent;
}
$this->_assignConfigVars($ptr, $tpl, $_config_vars);
}
}
}
}
/**
* Assign all config variables in given scope
*
* @param \Smarty_Internal_Data $scope_ptr
* @param \Smarty_Internal_Template $tpl
* @param array $_config_vars
*/
public function _assignConfigVars(Smarty_Internal_Data $scope_ptr, Smarty_Internal_Template $tpl, $_config_vars)
{
// copy global config vars
foreach ($_config_vars['vars'] as $variable => $value) {
if ($tpl->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
$scope_ptr->config_vars[$variable] = $value;
} else {
$scope_ptr->config_vars[$variable] =
array_merge((array) $scope_ptr->config_vars[$variable], (array) $value);
}
}
// scan sections
$sections = $tpl->source->config_sections;
if (!empty($sections)) {
foreach ((array) $sections as $tpl_section) {
if (isset($_config_vars['sections'][$tpl_section])) {
foreach ($_config_vars['sections'][$tpl_section]['vars'] as $variable => $value) {
if ($tpl->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
$scope_ptr->config_vars[$variable] = $value;
} else {
$scope_ptr->config_vars[$variable] =
array_merge((array) $scope_ptr->config_vars[$variable], (array) $value);
}
}
}
}
}
}
/**
* gets a config variable value
*
* @param \Smarty_Internal_Template $tpl template object
* @param string $varName the name of the config variable
* @param bool $errorEnable
*
* @return mixed the value of the config variable
*/
public function _getConfigVariable(\Smarty_Internal_Template $tpl, $varName, $errorEnable = true)
{
$_ptr = $tpl;
while ($_ptr !== null) {
if (isset($_ptr->config_vars[$varName])) {
// found it, return it
return $_ptr->config_vars[$varName];
}
// not found, try at parent
$_ptr = $_ptr->parent;
}
if ($tpl->smarty->error_unassigned && $errorEnable) {
// force a notice
$x = $$varName;
}
return null;
}
}
@@ -0,0 +1,44 @@
<?php
/**
* Smarty Method CreateData
*
* Smarty::createData() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_CreateData
{
/**
* Valid for Smarty and template object
*
* @var int
*/
public $objMap = 3;
/**
* creates a data object
*
* @api Smarty::createData()
* @link http://www.smarty.net/docs/en/api.create.data.tpl
*
* @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
* @param \Smarty_Internal_Template|\Smarty_Internal_Data|\Smarty_Data|\Smarty $parent next higher level of Smarty
* variables
* @param string $name optional data block name
*
* @returns Smarty_Data data object
*/
public function createData(Smarty_Internal_TemplateBase $obj, Smarty_Internal_Data $parent = null, $name = null)
{
/* @var Smarty $smarty */
$smarty = isset($this->smarty) ? $this->smarty : $obj;
$dataObj = new Smarty_Data($parent, $smarty, $name);
if ($smarty->debugging) {
Smarty_Internal_Debug::register_data($dataObj);
}
return $dataObj;
}
}
@@ -0,0 +1,37 @@
<?php
/**
* Smarty Method GetAutoloadFilters
*
* Smarty::getAutoloadFilters() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_GetAutoloadFilters extends Smarty_Internal_Method_SetAutoloadFilters
{
/**
* Get autoload filters
*
* @api Smarty::getAutoloadFilters()
*
* @param \Smarty_Internal_TemplateBase|\Smarty_Internal_Template|\Smarty $obj
* @param string $type type of filter to get auto loads
* for. Defaults to all autoload
* filters
*
* @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type
* was specified
*/
public function getAutoloadFilters(Smarty_Internal_TemplateBase $obj, $type = null)
{
$smarty = isset($obj->smarty) ? $obj->smarty : $obj;
if ($type !== null) {
$this->_checkFilterType($type);
return isset($smarty->autoload_filters[$type]) ? $smarty->autoload_filters[$type] : array();
}
return $smarty->autoload_filters;
}
}
@@ -0,0 +1,58 @@
<?php
/**
* Smarty Method GetConfigVars
*
* Smarty::getConfigVars() method
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
class Smarty_Internal_Method_GetConfigVars
{
/**
* Valid for all objects
*
* @var int
*/
public $objMap = 7;
/**
* Returns a single or all config variables
*
* @api Smarty::getConfigVars()
* @link http://www.smarty.net/docs/en/api.get.config.vars.tpl
*
* @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
* @param string $varname variable name or null
* @param bool $search_parents include parent templates?
*
* @return mixed variable value or or array of variables
*/
public function getConfigVars(Smarty_Internal_Data $data, $varname = null, $search_parents = true)
{
$_ptr = $data;
$var_array = array();
while ($_ptr !== null) {
if (isset($varname)) {
if (isset($_ptr->config_vars[$varname])) {
return $_ptr->config_vars[$varname];
}
} else {
$var_array = array_merge($_ptr->config_vars, $var_array);
}
// not found, try at parent
if ($search_parents) {
$_ptr = $_ptr->parent;
} else {
$_ptr = null;
}
}
if (isset($varname)) {
return '';
} else {
return $var_array;
}
}
}

Some files were not shown because too many files have changed in this diff Show More