bug #385 update to smarty-3.1.28-dev (from Github)

This commit is contained in:
plegall 2015-12-10 14:02:22 +01:00
commit fa10e0945e
217 changed files with 22639 additions and 13502 deletions

22
include/smarty/.gitattributes vendored Normal file
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
include/smarty/.gitignore vendored Normal file
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

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 ./

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"
}

View file

@ -0,0 +1,67 @@
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
the compiled code of {include} subtemplates gets also merged in compiled inheritance template.
Merging the code into a single compile template has some drawbacks.
1. You could not use variable file names in {include} Smarty would use the {include} of compilation time.
2. You could not use individual compile_id in {include}
3. Seperate caching of subtemplate was not possible
4. Any change of the template directory structure between calls was not necessarily seen.
Starting with 3.1.15 some of the above conditions got checked and resulted in an exception. It turned out
that a couple of users did use some of above and now got exceptions.
To resolve this starting with 3.1.16 there is a new configuration parameter $inheritance_merge_compiled_includes.
For most backward compatibility its default setting is true.
With this setting all {include} subtemplate will be merge into the compiled inheritance template, but the above cases
could be rejected by exception.
If $smarty->inheritance_merge_compiled_includes = false; {include} subtemplate will not be merged.
You must now manually merge all {include} subtemplate which do contain {block} tags. This is done by setting the "inline" option.
{include file='foo.bar' inline}
1. In case of a variable file name like {include file=$foo inline} you must use the variable in a compile_id $smarty->compile_id = $foo;
2. If you use individual compile_id in {include file='foo.tpl' compile_id=$bar inline} it must be used in the
global compile_id as well $smarty->compile_id = $bar;
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.

View file

@ -0,0 +1,128 @@
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 the get tne content of another template.
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)
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;}, 'clousre_1');
- $smarty->registerFilter('pre', function($source) {return $source;}, 'clousre_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.
.

View file

@ -1,4 +1,4 @@
Smarty 3.1.13
Smarty 3.x
Author: Monte Ohrt <monte at ohrt dot com >
Author: Uwe Tews
@ -120,7 +120,7 @@ $smarty->unregisterObject($object_name)
$smarty->unregisterFilter($type, $function_name)
$smarty->unregisterResource($resource_type)
$smarty->compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
$smarty->compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
$smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
$smarty->testInstall()
@ -460,10 +460,11 @@ 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 Smarty 2 internals.

65
include/smarty/README.md Normal file
View file

@ -0,0 +1,65 @@
#Smarty 3 template engine
##Distribution repository
> Smarty 3.1.28 introduces run time template inheritance
> Read the NEW_FEATURES and INHERITANCE_RELEASE_NOTES file for recent extensions to Smarty 3.1 functionality
Smarty versions 3.1.11 or later are now on github and can be installed with Composer.
The "smarty/smarty" package will start at libs/.... subfolder.
To get the latest stable version of Smarty 3.1 use
```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

View file

@ -199,7 +199,7 @@ Relative paths are available with {include file="..."} and
$smarty->fetch('./foo.tpl') cannot be relative to a template, an
exception is thrown.
Adressing a specific $template_dir
Addressing a specific $template_dir
Smarty 3.1 introduces the $template_dir index notation.
$smarty->fetch('[foo]bar.tpl') and {include file="[foo]bar.tpl"}

View file

@ -1,9 +1,679 @@
===== Smarty-3.1.13 =====
 ===== 3.1.28-dev===== (xx.xx.2015)
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)
14.10.2014
- bugfix any tag placed within "<script language=php>" will throw a security exception to close all thinkable holes
- bugfix classmap in root composer.json should start at "libs/..."
- improvement cache is_file(file_exists) results of loadPlugin() to avoid unnecessary calls during compilation (Issue 201}
12.10.2014
- bugfix a comment like "<script{*foo*} language=php>" bypassed $php_handling checking (Thue Kristensen)
- bugfix change of 08.10.2014 could create E_NOTICE meassage when using "<?php" tags
- bugfix "<script language=php>" with $php_handling PHP_PASSTHRU was executed in {nocache} sections
===== 3.1.20 ===== (09.10.2014)
08.10.2014
- bugfix security mode of "<script language=php>" must be controlled by $php_handling property (Thue Kristensen)
01.10.2014
- bugfix template resource of inheritance blocks could get invalid if the default resource type is not 'file'(Issue 202)
- bugfix existing child {block} tag must override parent {block} tag append / prepend setting (topic 25259)
02.08.2014
- bugfix modifier wordwrap did output break string wrong if first word was exceeding length with cut = true (topic 25193)
24.07.2014
- bugfix cache clear when cache folder does not exist
16.07.2014
- enhancement remove BOM automatically from template source (topic 25161)
04.07.2014
- bugfix the bufix of 02.06.2014 broke correct handling of child templates with same name but different template folders in extends resource (issue 194 and topic 25099)
===== 3.1.19 ===== (30.06.2014)
20.06.2014
- bugfix template variables could not be passed as parameter in {include} when the include was in a {nocache} section (topic 25131)
17.06.2014
- bugfix large template text of some charsets could cause parsing errors (topic 24630)
08.06.2014
- bugfix registered objects did not work after spelling fixes of 06.06.2014
- bugfix {block} tags within {literal} .. {/literal} got not displayed correctly (topic 25024)
- bugfix UNC WINDOWS PATH like "\\psf\path\to\dir" did not work as template directory (Issue 192)
- bugfix {html_image} security check did fail on files relative to basedir (Issue 191)
06.06.2014
- fixed PHPUnit outputFilterTrimWhitespaceTests.php assertion of test result
- fixed spelling, PHPDoc , minor errors, code cleanup
02.06.2014
- using multiple cwd with relative template dirs could result in identical compiled file names. (issue 194 and topic 25099)
19.04.2014
- bugfix calling createTemplate(template, data) with empty data array caused notice of array to string conversion (Issue 189)
- bugfix clearCompiledTemplate() did not delete files on WINDOWS when a compile_id was specified
18.04.2014
- revert bugfix of 5.4.2014 because %-e date format is not supported on all operating systems
===== 3.1.18 ===== (07.04.2014)
06.04.2014
- bugfix template inheritance fail when using custom resource after patch of 8.3.2014 (Issue 187)
- bugfix update of composer file (Issue 168 and 184)
05.04.2014
- bugfix default date format leads to extra spaces when displaying dates with single digit days (Issue 165)
26.03.2014
- bugfix Smart_Resource_Custom should not lowercase the resource name (Issue 183)
24.03.2014
- bugfix using a {foreach} property like @iteration could fail when used in inheritance parent templates (Issue 182)
20.03.2014
- bugfix $smarty->auto_literal and mbsting.func_overload 2, 6 or 7 did fail (forum topic 24899)
18.03.2014
- revert change of 17.03.2014
17.03.2014
- bugfix $smarty->auto_literal and mbsting.func_overload 2, 6 or 7 did fail (forum topic 24899)
15.03.2014
- bugfix Smarty_CacheResource_Keyvaluestore did use different keys on read/writes and clearCache() calls (Issue 169)
13.03.2014
- bugfix clearXxx() change of 27.1.2014 did not work when specifing cache_id or compile_id (forum topic 24868 and 24867)
===== 3.1.17 =====
08.03.2014
- bugfix relative file path {include} within {block} of child templates did throw exception on first call (Issue 177)
17.02.2014
- bugfix Smarty failed when executing PHP on HHVM (Hip Hop 2.4) because uniqid('',true) does return string with ',' (forum topic 20343)
16.02.2014
- bugfix a '//' or '\\' in template_dir path could produce wrong path on relative filepath in {include} (Issue 175)
05.02.2014
- bugfix shared.literal_compiler_param.php did throw an exception when literal did contain a '-' (smarty-developers group)
27.01.2014
- bugfix $smarty->debugging = true; did show the variable of the $smarty object not the variables used in display() call (forum topic 24764)
- bugfix clearCompiledTemplate(), clearAll() and clear() should use realpath to avoid possible exception from RecursiveDirectoryIterator (Issue 171)
26.01.2014
- bugfix undo block nesting checks for {nocache} for reasons like forum topic 23280 (forum topic 24762)
18.01.2014
- bugfix the compiler did fail when using template inheritance and recursive {include} (smarty-developers group)
11.01.2014
- bugfix "* }" (spaces before right delimiter) was interpreted by mistake as comment end tag (Issue 170)
- internals content cache should be clear when updating cache file
08.01.2014
- bugfix Smarty_CacheResource_Custom did not handle template resource type specifications on clearCache() calls (Issue 169)
- bugfix SmartyBC.class.php should use require_once to load Smarty.class.php (forum topic 24683)
===== 3.1.16 =====
15.12.2013
- bugfix {include} with {block} tag handling (forum topic 24599, 24594, 24682) (Issue 161)
Read 3.1.16_RELEASE_NOTES for more details
- enhancement additional debug output at $smarty->_parserdebug = true;
07.11.2013
- bugfix too restrictive handling of {include} within {block} tags. 3.1.15 did throw errors where 3.1.14 did not (forum topic 24599)
- bugfix compiler could fail if PHP mbstring.func_overload is enabled (Issue 164)
28.10.2013
- bugfix variable resource name at custom resource plugin did not work within {block} tags (Issue 163)
- bugfix notice "Trying to get property of non-object" removed (Issue 163)
- bugfix correction of modifier capitalize fix from 3.10.2013 (issue 159)
- bugfix multiple {block}s with same name in parent did not work (forum topic 24631)
20.10.2013
- bugfix a variable file name at {extends} tag did fail (forum topic 24618)
14.10.2013
- bugfix yesterdays fix could result in an undefined variable
13.10.2013
- bugfix variable names on {include} in template inheritance did unextepted error message (forum topic 24594) (Issue 161)
.- bugfix relative includes with same name like {include './foo.tpl'} from different folder failed (forum topic 24590)(Issue 161)
04.10.2013
- bugfix variable file names at {extends} had been disbabled by mistake with the rewrite of
template inheritance of 24.08.2013 (forum topic 24585)
03.10.2013
- bugfix loops using modifier capitalize did eat up memory (issue 159)
===== Smarty 3.1.15 =====
01.10.2013
- use current delimiters in compiler error messages (issue 157)
- improvement on performance when using error handler and multiple template folders (issue 152)
17.09.2013
- improvement added patch for additional SmartyCompilerException properties for better access to scource information (forum topic 24559)
16.09.2013
- bugfix recompiled templates did not show on first request with zend opcache cache (forum topic 24320)
13.09.2013
- bugfix html_select_time defaulting error for the Meridian dropdown (forum topic 24549)
09.09.2012
- bugfix incorrect compiled code with array(object,method) callback at registered Variable Filter (forum topic 24542)
27.08.2013
- bugfix delimiter followed by linebreak did not work as auto literal after update from 24.08.2013 (forum topic 24518)
24.08.2013
- bugfix and enhancement
Because several recent problems with template inheritance the {block} tag compiler has been rewriten
- Error messages shown now the correct child template file and line number
- The compiler could fail on some larger UTF-8 text block (forum topic 24455)
- The {strip} tag can now be placed outside {block} tags in child templates (forum topic 24289)
- change SmartyException::$escape is now false by default
- change PHP traceback has been remove for SmartyException and SmartyCompilerException
14.08.2013
- bugfix compiled filepath of config file did not observe different config_dir (forum topic 24493)
13.08.2013
- bugfix the internal resource cache did not observe config_dir changes (forum topic 24493)
12.08.2013
- bugfix internal $tmpx variables must be unique over all inheritance templates (Issue 149)
10.08.2013
- bugfix a newline was eaten when a <?xml ... ?> was passed by a Smarty variable and caching was enabled (forum topic 24482)
29.07.2013
- bugfix headers already send warning thrown when using 'SMARTY_DEBUG=on' from URL (Issue 148)
27.07.2013
- enhancement allow access to properties of registered opjects for Smarty2 BC (forum topic 24344)
26.07.2013
- bugfix template inheritance nesting problem (forum topic 24387)
15.7.2013
- update code generated by PSR-2 standards fixer which introduced PHP 5.4 incompatibilities of 14.7.2013
14.7.2013
- bugfix increase of internal maximum parser stacksize to allow more complex tag code {forum topic 24426}
- update for PHP 5.4 compatibility
- reformat source to PSR-2 standard
12.7.2013
- bugfix Do not remove '//' from file path at normalization (Issue 142)
2.7.2013
- bugfix trimwhitespace would replace captured items in wrong order (forum topic 24387)
===== Smarty-3.1.14 =====
27.06.2013
- bugfix removed PHP 5.5 deprecated preg_replace /e option in modifier capitalize (forum topic 24389)
17.06.2013
- fixed spelling in sources and documentation (from smarty-developers forum Veres Lajos)
- enhancement added constant SMARTY::CLEAR_EXPIRED for the change of 26.05.2013 (forum topic 24310)
- bugfix added smarty_security.php to composer.json (Issue 135)
26.05.2013
- enhancement an expire_time of -1 in clearCache() and clearAllCache() will delete outdated cache files
by their individual cache_lifetime used at creation (forum topic 24310)
21.05.2013
- bugfix modifier strip_tags:true was compiled into wrong code (Forum Topic 24287)
- bugfix /n after ?> in Smarty.class.php did start output buffering (Issue 138)
25.04.2013
- bugfix escape and wordrap modifier could be compiled into wrong code when used in {nocache}{/nocache}
section but caching is disabled (Forum Topic 24260)
05.04.2013
- bugfix post filter must not run when compiling inheritance child blocks (Forum Topic 24094)
- bugfix after the fix for Issue #130 compiler exceptions got double escaped (Forum Topic 24199)
28.02.2013
- bugfix nocache blocks could be lost when using CACHING_LIFETIME_SAVED (Issue #133)
- bugfix Compile ID gets nulled when compiling child blocks (Issue #134)
24.01.2013
- bugfix wrong tag type in smarty_internal_templatecompilerbase.php could cause wrong plugin search order (Forum Topic 24028)
===== Smarty-3.1.13 =====
13.01.2013
- enhancement allow to disable exception message escaping by SmartyException::$escape = false; (Issue #130)
09.01.2013
- bugfix compilation did fail when a prefilter did modify an {extends} tag (Forum Topic 23966)
- bugfix compilation did fail when a prefilter did modify an {extends} tag c
- bugfix template inheritance could fail if nested {block} tags in childs did contain {$smarty.block.child} (Issue #127)
- bugfix template inheritance could fail if {block} tags in childs did have similar name as used plugins (Issue #128)
- added abstract method declaration doCompile() in Smarty_Internal_TemplateCompilerBase (Forum Topic 23969)
@ -417,7 +1087,7 @@
03/09/2011
- bugfix createTemplate() must default to cache_id and compile_id of Smarty object
- bugfix Smarty_CacheResource_KeyValueStore must include $source->uid in cache filepath to keep templates with same
name but different folders seperated
name but different folders separated
- added cacheresource.apc.php example in demo folder
02/09/2011
@ -470,7 +1140,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
@ -608,7 +1278,7 @@
- changed ./ and ../ behaviour
14/02/2011
- added {block ... hide} option to supress block if no child is defined
- added {block ... hide} option to suppress block if no child is defined
13/02/2011
- update handling of recursive subtemplate calls
@ -722,7 +1392,7 @@
- bugfix on compiler object destruction. compiler_object property was by mistake unset.
09/03/2011
-bugfix a variable filter should run before modifers on an output tag (see change of 23/07/2010)
-bugfix a variable filter should run before modifiers on an output tag (see change of 23/07/2010)
08/03/2011
- bugfix loading config file without section should load only defaults
@ -1026,10 +1696,10 @@ request_use_auto_globals
- bugfix passing scope attributes in doublequoted strings did not work at {include} {assign} and {append}
25/07/2010
- another bugfix of change from 23/07/2010 when compiling modifer
- another bugfix of change from 23/07/2010 when compiling modifier
24/07/2010
- bugfix of change from 23/07/2010 when compiling modifer
- bugfix of change from 23/07/2010 when compiling modifier
23/07/2010
- changed execution order. A variable filter does now run before modifiers on output of variables
@ -1336,7 +2006,7 @@ request_use_auto_globals
- bugfix on {if} tags
01/12/2010
- changed back modifer handling in parser. Some restrictions still apply:
- changed back modifier handling in parser. Some restrictions still apply:
if modifiers are used in side {if...} expression or in mathematical expressions
parentheses must be used.
- bugfix the {function..} tag did not accept the name attribute in double quotes
@ -1948,7 +2618,7 @@ NOTICE: existing compiled template and cache files must be deleted
- fixed exceptions in function plugins
- fixed notice error in Smarty.class.php
- allow chained objects to span multiple lines
- fixed error in modifers
- fixed error in modifiers
03/20/2009
- moved /plugins folder into /libs folder
@ -1956,7 +2626,7 @@ NOTICE: existing compiled template and cache files must be deleted
- autoappend a directory separator if the xxxxx_dir definition have no trailing one
03/19/2009
- allow array definition as modifer parameter
- allow array definition as modifier parameter
- changed modifier to use multi byte string funktions.
03/17/2009

View file

@ -0,0 +1,43 @@
{
"name": "smarty/smarty",
"type": "library",
"description": "Smarty - the compiling PHP template engine",
"keywords": ["templating"],
"homepage": "http://www.smarty.net",
"license": "LGPL-3.0",
"authors": [
{
"name": "Monte Ohrt",
"email": "monte@ohrt.com"
},
{
"name": "Uwe Tews",
"email": "uwe.tews@googlemail.com"
},
{
"name": "Rodney Rehm",
"email": "rodney.rehm@medialize.de"
}
],
"support": {
"irc": "irc://irc.freenode.org/smarty",
"issues": "https://github.com/smarty-php/smarty/issues",
"forum": "http://www.smarty.net/forums/"
},
"require": {
"php": ">=5.2"
},
"autoload": {
"classmap": [
"libs/Smarty.class.php",
"libs/SmartyBC.class.php",
"libs/sysplugins/"
]
},
"extra": {
"branch-alias": {
"dev-master": "3.1.x-dev"
}
}
}

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;
}
*/
}

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;
}

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

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;
}
}

File diff suppressed because it is too large Load diff

View file

@ -3,21 +3,17 @@
* Project: Smarty: the PHP compiling template engine
* File: SmartyBC.class.php
* SVN: $Id: $
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For questions, help, comments, discussion, etc., please join the
* Smarty mailing list. Send a blank e-mail to
* smarty-discussion-subscribe@googlegroups.com
@ -32,21 +28,29 @@
/**
* @ignore
*/
require(dirname(__FILE__) . '/Smarty.class.php');
require_once(dirname(__FILE__) . '/Smarty.class.php');
/**
* Smarty Backward Compatability Wrapper Class
*
* @package Smarty
*/
class SmartyBC extends Smarty {
class SmartyBC extends Smarty
{
/**
* Smarty 2 BC
*
* @var string
*/
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
*
@ -55,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');
}
/**
@ -122,7 +124,10 @@ class SmartyBC extends Smarty {
* @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_functs list of methods that are block format
* @param array $block_methods list of methods that are block format
*
* @throws SmartyException
* @internal param array $block_functs list of methods that are block format
*/
public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
{
@ -309,6 +314,7 @@ class SmartyBC extends Smarty {
* @param string $cache_id name of cache_id
* @param string $compile_id name of compile_id
* @param string $exp_time expiration time
*
* @return boolean
*/
public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
@ -320,6 +326,7 @@ class SmartyBC extends Smarty {
* clear the entire contents of cache (all templates)
*
* @param string $exp_time expire time
*
* @return boolean
*/
public function clear_all_cache($exp_time = null)
@ -333,6 +340,7 @@ class SmartyBC extends Smarty {
* @param string $tpl_file name of template file
* @param string $cache_id
* @param string $compile_id
*
* @return boolean
*/
public function is_cached($tpl_file, $cache_id = null, $compile_id = null)
@ -356,6 +364,7 @@ class SmartyBC extends Smarty {
* @param string $tpl_file
* @param string $compile_id
* @param string $exp_time
*
* @return boolean results of {@link smarty_core_rm_auto()}
*/
public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
@ -367,6 +376,7 @@ class SmartyBC extends Smarty {
* Checks whether requested template exists.
*
* @param string $tpl_file
*
* @return boolean
*/
public function template_exists($tpl_file)
@ -378,6 +388,7 @@ class SmartyBC extends Smarty {
* Returns an array containing template variables
*
* @param string $name
*
* @return array
*/
public function get_template_vars($name = null)
@ -389,6 +400,7 @@ class SmartyBC extends Smarty {
* Returns an array containing config variables
*
* @param string $name
*
* @return array
*/
public function get_config_vars($name = null)
@ -412,6 +424,7 @@ class SmartyBC extends Smarty {
* return a reference to a registered object
*
* @param string $name
*
* @return object
*/
public function get_registered_object($name)
@ -439,22 +452,4 @@ 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 '';
}
?>

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 @@ h2 {
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 @@ th, td {
font-family: monospace;
vertical-align: top;
text-align: left;
width: 50%;
}
td {
@ -74,27 +80,40 @@ td {
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 {
color: maroon;
}
{/literal}
</style>
</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">
<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>
@ -107,18 +126,25 @@ td {
<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>
<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></tr>
<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}
</table>
@ -126,8 +152,9 @@ td {
</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>

View file

@ -8,7 +8,6 @@
/**
* Smarty {textformat}{/textformat} block plugin
*
* Type: block function<br>
* Name: textformat<br>
* Purpose: format text a certain way with preset styles
@ -25,10 +24,12 @@
*
* @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat}
* (Smarty online manual)
*
* @param array $params parameters
* @param string $content contents of the block
* @param Smarty_Internal_Template $template template object
* @param boolean &$repeat repeat flag
*
* @return string content re-formatted
* @author Monte Ohrt <monte at ohrt dot com>
*/
@ -76,8 +77,6 @@ function smarty_block_textformat($params, $content, $template, &$repeat)
}
// split into paragraphs
$_paragraphs = preg_split('![\r\n]{2}!', $content);
$_output = '';
foreach ($_paragraphs as &$_paragraph) {
if (!$_paragraph) {
@ -109,5 +108,3 @@ function smarty_block_textformat($params, $content, $template, &$repeat)
return $_output;
}
}
?>

View file

@ -1,13 +1,13 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {counter} function plugin
*
* Type: function<br>
* Name: counter<br>
* Purpose: print out a counter value
@ -15,8 +15,10 @@
* @author Monte Ohrt <monte at ohrt dot com>
* @link http://www.smarty.net/manual/en/language.function.counter.php {counter}
* (Smarty online manual)
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string|null
*/
function smarty_function_counter($params, $template)
@ -66,13 +68,11 @@ function smarty_function_counter($params, $template)
$counter['direction'] = $params['direction'];
}
if ($counter['direction'] == "down")
if ($counter['direction'] == "down") {
$counter['count'] -= $counter['skip'];
else
} else {
$counter['count'] += $counter['skip'];
return $retval;
}
?>
return $retval;
}

View file

@ -8,7 +8,6 @@
/**
* Smarty {cycle} function plugin
*
* Type: function<br>
* Name: cycle<br>
* Date: May 3, 2002<br>
@ -38,8 +37,10 @@
* @author credit to Gerard <gerard@interfold.com>
* @author credit to Jason Sweat <jsweat_php@yahoo.com>
* @version 1.3
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string|null
*/
@ -55,11 +56,13 @@ function smarty_function_cycle($params, $template)
if (!isset($params['values'])) {
if (!isset($cycle_vars[$name]['values'])) {
trigger_error("cycle: missing 'values' parameter");
return;
}
} else {
if (isset($cycle_vars[$name]['values'])
&& $cycle_vars[$name]['values'] != $params['values'] ) {
&& $cycle_vars[$name]['values'] != $params['values']
) {
$cycle_vars[$name]['index'] = 0;
}
$cycle_vars[$name]['values'] = $params['values'];
@ -102,5 +105,3 @@ function smarty_function_cycle($params, $template)
return $retval;
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty {fetch} plugin
*
* Type: function<br>
* Name: fetch<br>
* Purpose: fetch file, web or ftp data and display results
@ -16,14 +15,18 @@
* @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @throws SmartyException
* @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable
*/
function smarty_function_fetch($params, $template)
{
if (empty($params['file'])) {
trigger_error("[plugin] fetch parameter 'file' cannot be empty", E_USER_NOTICE);
return;
}
@ -101,6 +104,7 @@ function smarty_function_fetch($params, $template)
if (!empty($param_value)) {
if (!preg_match('![\w\d-]+: .+!', $param_value)) {
trigger_error("[plugin] invalid header format '" . $param_value . "'", E_USER_NOTICE);
return;
} else {
$extra_headers[] = $param_value;
@ -117,6 +121,7 @@ function smarty_function_fetch($params, $template)
$proxy_port = (int) $param_value;
} else {
trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
return;
}
break;
@ -135,11 +140,13 @@ function smarty_function_fetch($params, $template)
$timeout = (int) $param_value;
} else {
trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
return;
}
break;
default:
trigger_error("[plugin] unrecognized attribute '" . $param_key . "'", E_USER_NOTICE);
return;
}
}
@ -152,6 +159,7 @@ function smarty_function_fetch($params, $template)
if (!$fp) {
trigger_error("[plugin] unable to fetch: $errstr ($errno)", E_USER_NOTICE);
return;
} else {
if ($_is_proxy) {
@ -195,6 +203,7 @@ function smarty_function_fetch($params, $template)
}
} else {
trigger_error("[plugin fetch] unable to parse URL, check syntax", E_USER_NOTICE);
return;
}
} else {
@ -210,5 +219,3 @@ function smarty_function_fetch($params, $template)
return $content;
}
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty {html_checkboxes} function plugin
*
* File: function.html_checkboxes.php<br>
* Type: function<br>
* Name: html_checkboxes<br>
@ -37,8 +36,10 @@
* @author Christopher Kvarme <christopher.kvarme@flashjab.com>
* @author credits to Monte Ohrt <monte at ohrt dot com>
* @version 1.0
*
* @param array $params parameters
* @param object $template template object
*
* @return string
* @uses smarty_function_escape_special_chars()
*/
@ -116,7 +117,8 @@ function smarty_function_html_checkboxes($params, $template)
case 'assign':
break;
case 'strict': break;
case 'strict':
break;
case 'disabled':
case 'readonly':
@ -143,8 +145,9 @@ function smarty_function_html_checkboxes($params, $template)
}
}
if (!isset($options) && !isset($values))
return ''; /* raise error here? */
if (!isset($options) && !isset($values)) {
return '';
} /* raise error here? */
$_html_result = array();
@ -164,10 +167,10 @@ function smarty_function_html_checkboxes($params, $template)
} else {
return implode("\n", $_html_result);
}
}
function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape=true) {
function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape = true)
{
$_output = '';
if (is_object($value)) {
@ -175,6 +178,7 @@ function smarty_function_html_checkboxes_output($name, $value, $output, $selecte
$value = (string) $value->__toString();
} else {
trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
return '';
}
} else {
@ -186,6 +190,7 @@ function smarty_function_html_checkboxes_output($name, $value, $output, $selecte
$output = (string) $output->__toString();
} else {
trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE);
return '';
}
} else {
@ -227,7 +232,6 @@ function smarty_function_html_checkboxes_output($name, $value, $output, $selecte
}
$_output .= $separator;
return $_output;
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty {html_image} function plugin
*
* Type: function<br>
* Name: html_image<br>
* Date: Feb 24, 2003<br>
@ -29,8 +28,11 @@
* @author Monte Ohrt <monte at ohrt dot com>
* @author credits to Duda <duda@big.hu>
* @version 1.0
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @throws SmartyException
* @return string
* @uses smarty_function_escape_special_chars()
*/
@ -84,6 +86,7 @@ function smarty_function_html_image($params, $template)
if (empty($file)) {
trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
return;
}
@ -111,7 +114,7 @@ function smarty_function_html_image($params, $template)
}
} else {
// local file
if(!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
if (!$template->smarty->security_policy->isTrustedResourceDir($_image_path)) {
return;
}
}
@ -122,12 +125,15 @@ function smarty_function_html_image($params, $template)
if (!$_image_data = @getimagesize($_image_path)) {
if (!file_exists($_image_path)) {
trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
return;
} elseif (!is_readable($_image_path)) {
trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
return;
} else {
trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
return;
}
}
@ -155,5 +161,3 @@ function smarty_function_html_image($params, $template)
return $prefix . '<img src="' . $path_prefix . $file . '" alt="' . $alt . '" width="' . $width . '" height="' . $height . '"' . $extra . ' />' . $suffix;
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty {html_options} function plugin
*
* Type: function<br>
* Name: html_options<br>
* Purpose: Prints the list of <option> tags generated from
@ -28,12 +27,13 @@
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author Ralf Strehle (minor optimization) <ralf dot strehle at yahoo dot de>
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string
* @uses smarty_function_escape_special_chars()
*/
function smarty_function_html_options($params, $template)
function smarty_function_html_options($params)
{
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
@ -91,7 +91,8 @@ function smarty_function_html_options($params, $template)
}
break;
case 'strict': break;
case 'strict':
break;
case 'disabled':
case 'readonly':
@ -120,6 +121,7 @@ function smarty_function_html_options($params, $template)
if (!isset($options) && !isset($values)) {
/* raise error here? */
return '';
}
@ -165,6 +167,7 @@ function smarty_function_html_options_optoutput($key, $value, $selected, $id, $c
$value = smarty_function_escape_special_chars((string) $value->__toString());
} else {
trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
return '';
}
} else {
@ -177,6 +180,7 @@ function smarty_function_html_options_optoutput($key, $value, $selected, $id, $c
$_html_result = smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id . '-' . $idx) : null, $class, $_idx);
$idx ++;
}
return $_html_result;
}
@ -187,7 +191,6 @@ function smarty_function_html_options_optgroup($key, $values, $selected, $id, $c
$optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $idx);
}
$optgroup_html .= "</optgroup>\n";
return $optgroup_html;
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty {html_radios} function plugin
*
* File: function.html_radios.php<br>
* Type: function<br>
* Name: html_radios<br>
@ -37,8 +36,10 @@
* @author Christopher Kvarme <christopher.kvarme@flashjab.com>
* @author credits to Monte Ohrt <monte at ohrt dot com>
* @version 1.0
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string
* @uses smarty_function_escape_special_chars()
*/
@ -102,7 +103,8 @@ function smarty_function_html_radios($params, $template)
case 'assign':
break;
case 'strict': break;
case 'strict':
break;
case 'disabled':
case 'readonly':
@ -131,6 +133,7 @@ function smarty_function_html_radios($params, $template)
if (!isset($options) && !isset($values)) {
/* raise error here? */
return '';
}
@ -163,6 +166,7 @@ function smarty_function_html_radios_output($name, $value, $output, $selected, $
$value = (string) $value->__toString();
} else {
trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
return '';
}
} else {
@ -174,6 +178,7 @@ function smarty_function_html_radios_output($name, $value, $output, $selected, $
$output = (string) $output->__toString();
} else {
trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE);
return '';
}
} else {
@ -211,7 +216,6 @@ function smarty_function_html_radios_output($name, $value, $output, $selected, $
}
$_output .= $separator;
return $_output;
}
?>

View file

@ -17,11 +17,9 @@ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
/**
* Smarty {html_select_date} plugin
*
* Type: function<br>
* Name: html_select_date<br>
* Purpose: Prints the dropdowns for date selection.
*
* ChangeLog:
* <pre>
* - 1.0 initial release
@ -47,11 +45,12 @@ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
* @author Andrei Zmievski
* @author Monte Ohrt <monte at ohrt dot com>
* @author Rodney Rehm
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string
*/
function smarty_function_html_select_date($params, $template)
function smarty_function_html_select_date($params)
{
// generate timestamps used for month names only
static $_month_timestamps = null;
@ -187,7 +186,6 @@ function smarty_function_html_select_date($params, $template)
? $params['time'][$prefix . $_elementName]
: date($_elementKey);
}
$time = mktime(0, 0, 0, $_month, $_day, $_year);
} elseif (isset($params['time'][$field_array][$prefix . 'Year'])) {
// $_REQUEST given
foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
@ -196,7 +194,6 @@ function smarty_function_html_select_date($params, $template)
? $params['time'][$field_array][$prefix . $_elementName]
: date($_elementKey);
}
$time = mktime(0, 0, 0, $_month, $_day, $_year);
} else {
// no date found, use NOW
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
@ -219,9 +216,9 @@ function smarty_function_html_select_date($params, $template)
if ($t === null) {
$$key = (int) $_current_year;
} elseif ($t[0] == '+') {
$$key = (int)($_current_year + trim(substr($t, 1)));
$$key = (int) ($_current_year + (int)trim(substr($t, 1)));
} elseif ($t[0] == '-') {
$$key = (int)($_current_year - trim(substr($t, 1)));
$$key = (int) ($_current_year - (int)trim(substr($t, 1)));
} else {
$$key = (int) $$key;
}
@ -236,7 +233,6 @@ function smarty_function_html_select_date($params, $template)
// generate year <select> or <input>
if ($display_years) {
$_html_years = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year');
if ($all_extra) {
@ -277,7 +273,6 @@ function smarty_function_html_select_date($params, $template)
// generate month <select> or <input>
if ($display_months) {
$_html_month = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month');
if ($all_extra) {
@ -316,7 +311,6 @@ function smarty_function_html_select_date($params, $template)
// generate day <select> or <input>
if ($display_days) {
$_html_day = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day');
if ($all_extra) {
@ -388,7 +382,6 @@ function smarty_function_html_select_date($params, $template)
break;
}
}
return $_html;
}
?>

View file

@ -17,7 +17,6 @@ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
/**
* Smarty {html_select_time} function plugin
*
* Type: function<br>
* Name: html_select_time<br>
* Purpose: Prints the dropdowns for time selection
@ -26,12 +25,13 @@ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
* (Smarty online manual)
* @author Roberto Berto <roberto@berto.net>
* @author Monte Ohrt <monte AT ohrt DOT com>
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string
* @uses smarty_make_timestamp()
*/
function smarty_function_html_select_time($params, $template)
function smarty_function_html_select_time($params)
{
$prefix = "Time_";
$field_array = null;
@ -345,7 +345,7 @@ function smarty_function_html_select_time($params, $template)
$_html_meridian .= '<option value="">' . (isset($meridian_empty) ? $meridian_empty : $all_empty) . '</option>' . $option_separator;
}
$_html_meridian .= '<option value="am"'. ($_hour < 12 ? ' selected="selected"' : '') .'>AM</option>' . $option_separator
$_html_meridian .= '<option value="am"' . ($_hour > 0 && $_hour < 12 ? ' selected="selected"' : '') . '>AM</option>' . $option_separator
. '<option value="pm"' . ($_hour < 12 ? '' : ' selected="selected"') . '>PM</option>' . $option_separator
. '</select>';
}
@ -362,5 +362,3 @@ function smarty_function_html_select_time($params, $template)
return $_html;
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty {html_table} function plugin
*
* Type: function<br>
* Name: html_table<br>
* Date: Feb 17, 2003<br>
@ -43,11 +42,12 @@
* @version 1.1
* @link http://www.smarty.net/manual/en/language.function.html.table.php {html_table}
* (Smarty online manual)
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string
*/
function smarty_function_html_table($params, $template)
function smarty_function_html_table($params)
{
$table_attr = 'border="1"';
$tr_attr = '';
@ -64,6 +64,7 @@ function smarty_function_html_table($params, $template)
if (!isset($params['loop'])) {
trigger_error("html_table: missing 'loop' parameter", E_USER_WARNING);
return;
}
@ -173,5 +174,3 @@ function smarty_function_html_table_cycle($name, $var, $no)
return ($ret) ? ' ' . $ret : '';
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty {mailto} function plugin
*
* Type: function<br>
* Name: mailto<br>
* Date: May 21, 2002
@ -44,17 +43,19 @@
* @version 1.2
* @author Monte Ohrt <monte at ohrt dot com>
* @author credits to Jason Sweat (added cc, bcc and subject functionality)
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string
*/
function smarty_function_mailto($params, $template)
function smarty_function_mailto($params)
{
static $_allowed_encoding = array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true);
$extra = '';
if (empty($params['address'])) {
trigger_error("mailto: missing 'address' parameter", E_USER_WARNING);
return;
} else {
$address = $params['address'];
@ -71,8 +72,9 @@ function smarty_function_mailto($params, $template)
case 'cc':
case 'bcc':
case 'followupto':
if (!empty($value))
if (!empty($value)) {
$mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value));
}
break;
case 'subject':
@ -95,6 +97,7 @@ function smarty_function_mailto($params, $template)
$encode = (empty($params['encode'])) ? 'none' : $params['encode'];
if (!isset($_allowed_encoding[$encode])) {
trigger_error("mailto: 'encode' parameter must be none, javascript, javascript_charcode or hex", E_USER_WARNING);
return;
}
// FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
@ -126,6 +129,7 @@ function smarty_function_mailto($params, $template)
preg_match('!^(.*)(\?.*)$!', $address, $match);
if (!empty($match[2])) {
trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.", E_USER_WARNING);
return;
}
$address_encode = '';
@ -142,11 +146,10 @@ function smarty_function_mailto($params, $template)
}
$mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>';
} else {
// no encoding
return '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
}
}
?>

View file

@ -1,15 +1,14 @@
<?php
/**
* Smarty plugin
*
* This plugin is only for Smarty2 BC
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {math} function plugin
*
* Type: function<br>
* Name: math<br>
* Purpose: handle math computations in template
@ -17,8 +16,10 @@
* @link http://www.smarty.net/manual/en/language.function.math.php {math}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param array $params parameters
* @param Smarty_Internal_Template $template template object
*
* @return string|null
*/
function smarty_function_math($params, $template)
@ -31,6 +32,7 @@ function smarty_function_math($params, $template)
// be sure equation parameter is present
if (empty($params['equation'])) {
trigger_error("math: missing equation parameter", E_USER_WARNING);
return;
}
@ -39,6 +41,7 @@ function smarty_function_math($params, $template)
// make sure parenthesis are balanced
if (substr_count($equation, "(") != substr_count($equation, ")")) {
trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
return;
}
@ -48,6 +51,7 @@ function smarty_function_math($params, $template)
foreach ($match[1] as $curr_var) {
if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) {
trigger_error("math: function call $curr_var not allowed", E_USER_WARNING);
return;
}
}
@ -57,10 +61,12 @@ function smarty_function_math($params, $template)
// make sure value is not empty
if (strlen($val) == 0) {
trigger_error("math: parameter $key is empty", E_USER_WARNING);
return;
}
if (!is_numeric($val)) {
trigger_error("math: parameter $key: is not numeric", E_USER_WARNING);
return;
}
$equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
@ -83,5 +89,3 @@ function smarty_function_math($params, $template)
}
}
}
?>

View file

@ -8,16 +8,15 @@
/**
* Smarty capitalize modifier plugin
*
* Type: modifier<br>
* Name: capitalize<br>
* Purpose: capitalize words in the string
*
* {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }}
*
* @param string $string string to capitalize
* @param boolean $uc_digits also capitalize "x123" to "X123"
* @param boolean $lc_rest capitalize first letters, lowercase all following letters "aAa" to "Aaa"
*
* @return string capitalized string
* @author Monte Ohrt <monte at ohrt dot com>
* @author Rodney Rehm
@ -30,7 +29,7 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals
$upper_string = mb_convert_case($string, MB_CASE_TITLE, Smarty::$_CHARSET);
} else {
// uppercase word breaks
$upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').mb_convert_case(stripslashes('\\2'),MB_CASE_UPPER, '" . addslashes(Smarty::$_CHARSET) . "')", $string);
$upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_mbconvert_cb', $string);
}
// check uc_digits case
if (!$uc_digits) {
@ -40,7 +39,7 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals
}
}
}
$upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').mb_convert_case(stripslashes('\\3'),MB_CASE_UPPER, '" . addslashes(Smarty::$_CHARSET) . "')", $upper_string);
$upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_mbconvert2_cb', $upper_string);
return $upper_string;
}
@ -49,7 +48,7 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals
$string = strtolower($string);
}
// uppercase (including hyphenated words)
$upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').ucfirst(stripslashes('\\2'))", $string);
$upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_ucfirst_cb', $string);
// check uc_digits case
if (!$uc_digits) {
if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) {
@ -58,8 +57,34 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals
}
}
}
$upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').strtoupper(stripslashes('\\3'))", $upper_string);
$upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_ucfirst2_cb', $upper_string);
return $upper_string;
}
?>
/*
*
* Bug: create_function() use exhausts memory when used in long loops
* Fix: use declared functions for callbacks instead of using create_function()
* Note: This can be fixed using anonymous functions instead, but that requires PHP >= 5.3
*
* @author Kyle Renfrow
*/
function smarty_mod_cap_mbconvert_cb($matches)
{
return stripslashes($matches[1]) . mb_convert_case(stripslashes($matches[2]), MB_CASE_UPPER, Smarty::$_CHARSET);
}
function smarty_mod_cap_mbconvert2_cb($matches)
{
return stripslashes($matches[1]) . mb_convert_case(stripslashes($matches[3]), MB_CASE_UPPER, Smarty::$_CHARSET);
}
function smarty_mod_cap_ucfirst_cb($matches)
{
return stripslashes($matches[1]) . ucfirst(stripslashes($matches[2]));
}
function smarty_mod_cap_ucfirst2_cb($matches)
{
return stripslashes($matches[1]) . ucfirst(stripslashes($matches[3]));
}

View file

@ -8,7 +8,6 @@
/**
* Smarty date_format modifier plugin
*
* Type: modifier<br>
* Name: date_format<br>
* Purpose: format datestamps via strftime<br>
@ -19,10 +18,12 @@
*
* @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string input date string
* @param string $format strftime format for output
* @param string $default_date default date if $string is empty
* @param string $formatter either 'strftime' or 'auto'
*
* @return string |void
* @uses smarty_make_timestamp()
*/
@ -32,7 +33,7 @@ function smarty_modifier_date_format($string, $format=null, $default_date='', $f
$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') {
@ -56,10 +57,9 @@ function smarty_modifier_date_format($string, $format=null, $default_date='', $f
}
$format = str_replace($_win_from, $_win_to, $format);
}
return strftime($format, $timestamp);
} else {
return date($format, $timestamp);
}
}
?>

View file

@ -8,31 +8,36 @@
/**
* Smarty debug_print_var modifier plugin
*
* Type: modifier<br>
* Name: debug_print_var<br>
* Purpose: formats variable contents for display in the console
*
* @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 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;
@ -40,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;
@ -101,5 +114,3 @@ function smarty_modifier_debug_print_var ($var, $depth = 0, $length = 40)
return $results;
}
?>

View file

@ -8,17 +8,18 @@
/**
* Smarty escape modifier plugin
*
* Type: modifier<br>
* Name: escape<br>
* Purpose: escape string for output
*
* @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual)
* @link http://www.smarty.net/docs/en/language.modifier.escape
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string input string
* @param string $esc_type escape type
* @param string $char_set character set, used for htmlspecialchars() or htmlentities()
* @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities()
*
* @return string escaped input string
*/
function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true)
@ -46,6 +47,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
@ -65,6 +67,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
@ -83,6 +86,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlentities($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
@ -105,6 +109,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
for ($x = 0; $x < $_length; $x ++) {
$return .= '%' . bin2hex($string[$x]);
}
return $return;
case 'hexentity':
@ -115,6 +120,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
$return .= '&#x' . strtoupper(dechex($unicode)) . ';';
}
return $return;
}
// no MBString fallback
@ -122,6 +128,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
for ($x = 0; $x < $_length; $x ++) {
$return .= '&#x' . bin2hex($string[$x]) . ';';
}
return $return;
case 'decentity':
@ -132,6 +139,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
$return .= '&#' . $unicode . ';';
}
return $return;
}
// no MBString fallback
@ -139,6 +147,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
for ($x = 0; $x < $_length; $x ++) {
$return .= '&#' . ord($string[$x]) . ';';
}
return $return;
case 'javascript':
@ -148,6 +157,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
case 'mail':
if (Smarty::$_MBSTRING) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
return smarty_mb_str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
}
// no MBString fallback
@ -165,6 +175,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
$return .= chr($unicode);
}
}
return $return;
}
@ -178,11 +189,10 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
$return .= substr($string, $_i, 1);
}
}
return $return;
default:
return $string;
}
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty regex_replace modifier plugin
*
* Type: modifier<br>
* Name: regex_replace<br>
* Purpose: regular expression search/replace
@ -16,12 +15,15 @@
* @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
* regex_replace (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @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) {
@ -30,11 +32,13 @@ function smarty_modifier_regex_replace($string, $search, $replace)
} else {
$search = _smarty_regex_replace_check($search);
}
return preg_replace($search, $replace, $string);
return preg_replace($search, $replace, $string, $limit);
}
/**
* @param string $search string(s) that should be replaced
*
* @return string
* @ignore
*/
@ -49,7 +53,6 @@ function _smarty_regex_replace_check($search)
if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
$search = substr($search, 0, - strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
}
return $search;
}
?>

View file

@ -1,13 +1,13 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty replace modifier plugin
*
* Type: modifier<br>
* Name: replace<br>
* Purpose: simple search/replace
@ -15,19 +15,20 @@
* @link http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author Uwe Tews
*
* @param string $string input string
* @param string $search text to search for
* @param string $replace replacement text
*
* @return string
*/
function smarty_modifier_replace($string, $search, $replace)
{
if (Smarty::$_MBSTRING) {
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
return smarty_mb_str_replace($search, $replace, $string);
}
return str_replace($search, $replace, $string);
}
?>

View file

@ -1,21 +1,23 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/
/**
* Smarty spacify modifier plugin
*
* Type: modifier<br>
* Name: spacify<br>
* Purpose: add spaces between characters in a string
*
* @link http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string input string
* @param string $spacify_char string to insert between characters.
*
* @return string
*/
function smarty_modifier_spacify($string, $spacify_char = ' ')
@ -23,5 +25,3 @@ function smarty_modifier_spacify($string, $spacify_char = ' ')
// well… what about charsets besides latin and UTF-8?
return implode($spacify_char, preg_split('//' . Smarty::$_UTF8_MODIFIER, $string, - 1, PREG_SPLIT_NO_EMPTY));
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty truncate modifier plugin
*
* Type: modifier<br>
* Name: truncate<br>
* Purpose: Truncate a string to a certain length if necessary,
@ -17,16 +16,20 @@
*
* @link http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string input string
* @param integer $length length of truncated text
* @param string $etc end string
* @param boolean $break_words truncate at word boundary
* @param boolean $middle truncate in the middle of text
*
* @return string truncated string
*/
function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false) {
if ($length == 0)
function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false)
{
if ($length == 0) {
return '';
}
if (Smarty::$_MBSTRING) {
if (mb_strlen($string, Smarty::$_CHARSET) > $length) {
@ -37,8 +40,10 @@ function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_wo
if (!$middle) {
return mb_substr($string, 0, $length, Smarty::$_CHARSET) . $etc;
}
return mb_substr($string, 0, $length / 2, Smarty::$_CHARSET) . $etc . mb_substr($string, - $length / 2, $length, Smarty::$_CHARSET);
}
return $string;
}
@ -51,9 +56,9 @@ function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_wo
if (!$middle) {
return substr($string, 0, $length) . $etc;
}
return substr($string, 0, $length / 2) . $etc . substr($string, - $length / 2);
}
return $string;
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty cat modifier plugin
*
* Type: modifier<br>
* Name: cat<br>
* Date: Feb 24, 2003<br>
@ -19,12 +18,12 @@
* @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
* (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_cat($params, $compiler)
function smarty_modifiercompiler_cat($params)
{
return '(' . implode(').(', $params) . ')';
}
?>

View file

@ -8,17 +8,18 @@
/**
* Smarty count_characters modifier plugin
*
* Type: modifier<br>
* Name: count_characteres<br>
* Purpose: count the number of characters in a text
*
* @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_count_characters($params, $compiler)
function smarty_modifiercompiler_count_characters($params)
{
if (!isset($params[1]) || $params[1] != 'true') {
return 'preg_match_all(\'/[^\s]/' . Smarty::$_UTF8_MODIFIER . '\',' . $params[0] . ', $tmp)';
@ -29,5 +30,3 @@ function smarty_modifiercompiler_count_characters($params, $compiler)
// no MBString fallback
return 'strlen(' . $params[0] . ')';
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty count_paragraphs modifier plugin
*
* Type: modifier<br>
* Name: count_paragraphs<br>
* Purpose: count the number of paragraphs in a text
@ -16,13 +15,13 @@
* @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
* count_paragraphs (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_count_paragraphs($params, $compiler)
function smarty_modifiercompiler_count_paragraphs($params)
{
// count \r or \n characters
return '(preg_match_all(\'#[\r\n]+#\', ' . $params[0] . ', $tmp)+1)';
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty count_sentences modifier plugin
*
* Type: modifier<br>
* Name: count_sentences
* Purpose: count the number of sentences in a text
@ -16,13 +15,13 @@
* @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
* count_sentences (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_count_sentences($params, $compiler)
function smarty_modifiercompiler_count_sentences($params)
{
// find periods, question marks, exclamation marks with a word before but not after.
return 'preg_match_all("#\w[\.\?\!](\W|$)#S' . Smarty::$_UTF8_MODIFIER . '", ' . $params[0] . ', $tmp)';
}
?>

View file

@ -8,17 +8,18 @@
/**
* Smarty count_words modifier plugin
*
* Type: modifier<br>
* Name: count_words<br>
* Purpose: count the number of words in a text
*
* @link http://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_count_words($params, $compiler)
function smarty_modifiercompiler_count_words($params)
{
if (Smarty::$_MBSTRING) {
// return 'preg_match_all(\'#[\w\pL]+#' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)';
@ -28,5 +29,3 @@ function smarty_modifiercompiler_count_words($params, $compiler)
// no MBString fallback
return 'str_word_count(' . $params[0] . ')';
}
?>

View file

@ -8,17 +8,18 @@
/**
* Smarty default modifier plugin
*
* Type: modifier<br>
* Name: default<br>
* Purpose: designate default value for empty variables
*
* @link http://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_default ($params, $compiler)
function smarty_modifiercompiler_default($params)
{
$output = $params[0];
if (!isset($params[1])) {
@ -29,7 +30,6 @@ function smarty_modifiercompiler_default ($params, $compiler)
foreach ($params as $param) {
$output = '(($tmp = @' . $output . ')===null||$tmp===\'\' ? ' . $param . ' : $tmp)';
}
return $output;
}
?>

View file

@ -13,14 +13,16 @@ require_once( SMARTY_PLUGINS_DIR .'shared.literal_compiler_param.php' );
/**
* Smarty escape modifier plugin
*
* Type: modifier<br>
* Name: escape<br>
* Purpose: escape string for output
*
* @link http://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual)
* @author Rodney Rehm
*
* @param array $params parameters
* @param $compiler
*
* @return string with compiled code
*/
function smarty_modifiercompiler_escape($params, $compiler)
@ -105,21 +107,20 @@ function smarty_modifiercompiler_escape($params, $compiler)
case 'javascript':
// escape quotes and backslashes, newlines, etc.
return 'strtr(' . $params[0] . ', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/" ))';
}
} catch(SmartyException $e) {
}
catch (SmartyException $e) {
// pass through to regular plugin fallback
}
// could not optimize |escape call, so fallback to regular plugin
if ($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';
if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) {
$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';
}
return 'smarty_modifier_escape(' . join( ', ', $params ) . ')';
$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) . ')';
}

View file

@ -8,16 +8,17 @@
/**
* Smarty from_charset modifier plugin
*
* Type: modifier<br>
* Name: from_charset<br>
* Purpose: convert character encoding from $charset to internal encoding
*
* @author Rodney Rehm
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_from_charset($params, $compiler)
function smarty_modifiercompiler_from_charset($params)
{
if (!Smarty::$_MBSTRING) {
// FIXME: (rodneyrehm) shouldn't this throw an error?
@ -30,5 +31,3 @@ function smarty_modifiercompiler_from_charset($params, $compiler)
return 'mb_convert_encoding(' . $params[0] . ', "' . addslashes(Smarty::$_CHARSET) . '", ' . $params[1] . ')';
}
?>

View file

@ -1,24 +1,26 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty indent modifier plugin
*
* Type: modifier<br>
* Name: indent<br>
* Purpose: indent lines of text
*
* @link http://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_indent($params, $compiler)
function smarty_modifiercompiler_indent($params)
{
if (!isset($params[1])) {
$params[1] = 4;
@ -26,7 +28,6 @@ function smarty_modifiercompiler_indent($params, $compiler)
if (!isset($params[2])) {
$params[2] = "' '";
}
return 'preg_replace(\'!^!m\',str_repeat(' . $params[2] . ',' . $params[1] . '),' . $params[0] . ')';
}
?>

View file

@ -1,13 +1,13 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifierCompiler
*/
/**
* Smarty lower modifier plugin
*
* Type: modifier<br>
* Name: lower<br>
* Purpose: convert string to lowercase
@ -15,11 +15,13 @@
* @link http://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_lower($params, $compiler)
function smarty_modifiercompiler_lower($params)
{
if (Smarty::$_MBSTRING) {
return 'mb_strtolower(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
@ -27,5 +29,3 @@ function smarty_modifiercompiler_lower($params, $compiler)
// no MBString fallback
return 'strtolower(' . $params[0] . ')';
}
?>

View file

@ -8,18 +8,14 @@
/**
* Smarty noprint modifier plugin
*
* Type: modifier<br>
* Name: noprint<br>
* Purpose: return an empty string
*
* @author Uwe Tews
* @param array $params parameters
* @return string with compiled code
*/
function smarty_modifiercompiler_noprint($params, $compiler)
function smarty_modifiercompiler_noprint()
{
return "''";
}
?>

View file

@ -8,19 +8,18 @@
/**
* Smarty string_format modifier plugin
*
* Type: modifier<br>
* Name: string_format<br>
* Purpose: format strings via sprintf
*
* @link http://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_string_format($params, $compiler)
function smarty_modifiercompiler_string_format($params)
{
return 'sprintf(' . $params[1] . ',' . $params[0] . ')';
}
?>

View file

@ -8,7 +8,6 @@
/**
* Smarty strip modifier plugin
*
* Type: modifier<br>
* Name: strip<br>
* Purpose: Replace all repeated spaces, newlines, tabs
@ -18,16 +17,17 @@
*
* @link http://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_strip($params, $compiler)
function smarty_modifiercompiler_strip($params)
{
if (!isset($params[1])) {
$params[1] = "' '";
}
return "preg_replace('!\s+!" . Smarty::$_UTF8_MODIFIER . "', {$params[1]},{$params[0]})";
}
?>

View file

@ -8,26 +8,22 @@
/**
* Smarty strip_tags modifier plugin
*
* Type: modifier<br>
* 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)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_strip_tags($params, $compiler)
function smarty_modifiercompiler_strip_tags($params)
{
if (!isset($params[1])) {
$params[1] = true;
}
if ($params[1] === true) {
if (!isset($params[1]) || $params[1] === true || trim($params[1], '"') == 'true') {
return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})";
} else {
return 'strip_tags(' . $params[0] . ')';
}
}
?>

View file

@ -8,16 +8,17 @@
/**
* Smarty to_charset modifier plugin
*
* Type: modifier<br>
* Name: to_charset<br>
* Purpose: convert character encoding from internal encoding to $charset
*
* @author Rodney Rehm
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_to_charset($params, $compiler)
function smarty_modifiercompiler_to_charset($params)
{
if (!Smarty::$_MBSTRING) {
// FIXME: (rodneyrehm) shouldn't this throw an error?
@ -30,5 +31,3 @@ function smarty_modifiercompiler_to_charset($params, $compiler)
return 'mb_convert_encoding(' . $params[0] . ', ' . $params[1] . ', "' . addslashes(Smarty::$_CHARSET) . '")';
}
?>

View file

@ -8,16 +8,17 @@
/**
* Smarty unescape modifier plugin
*
* Type: modifier<br>
* Name: unescape<br>
* Purpose: unescape html entities
*
* @author Rodney Rehm
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_unescape($params, $compiler)
function smarty_modifiercompiler_unescape($params)
{
if (!isset($params[1])) {
$params[1] = 'html';
@ -47,5 +48,3 @@ function smarty_modifiercompiler_unescape($params, $compiler)
return $params[0];
}
}
?>

View file

@ -8,17 +8,18 @@
/**
* Smarty upper modifier plugin
*
* Type: modifier<br>
* Name: lower<br>
* Purpose: convert string to uppercase
*
* @link http://smarty.php.net/manual/en/language.modifier.upper.php lower (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
*
* @return string with compiled code
*/
function smarty_modifiercompiler_upper($params, $compiler)
function smarty_modifiercompiler_upper($params)
{
if (Smarty::$_MBSTRING) {
return 'mb_strtoupper(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
@ -26,5 +27,3 @@ function smarty_modifiercompiler_upper($params, $compiler)
// no MBString fallback
return 'strtoupper(' . $params[0] . ')';
}
?>

View file

@ -8,14 +8,16 @@
/**
* Smarty wordwrap modifier plugin
*
* Type: modifier<br>
* Name: wordwrap<br>
* Purpose: wrap a string of text at a given length
*
* @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual)
* @author Uwe Tews
*
* @param array $params parameters
* @param $compiler
*
* @return string with compiled code
*/
function smarty_modifiercompiler_wordwrap($params, $compiler)
@ -31,16 +33,15 @@ function smarty_modifiercompiler_wordwrap($params, $compiler)
}
$function = 'wordwrap';
if (Smarty::$_MBSTRING) {
if ($compiler->tag_nocache | $compiler->nocache) {
$compiler->template->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php';
if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) {
$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';
}
return $function . '(' . $params[0] . ',' . $params[1] . ',' . $params[2] . ',' . $params[3] . ')';
}
?>

View file

@ -8,16 +8,16 @@
/**
* Smarty trimwhitespace outputfilter plugin
*
* Trim unnecessary whitespace from HTML markup.
*
* @author Rodney Rehm
*
* @param string $source input string
* @param Smarty_Internal_Template $smarty Smarty object
*
* @return string filtered output
* @todo substr_replace() is not overloaded by mbstring.func_overload - so this function might fail!
*/
function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $smarty)
function smarty_outputfilter_trimwhitespace($source)
{
$store = array();
$_store = 0;
@ -45,7 +45,7 @@ function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $s
// 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, Smarty_Internal_Template $s
// 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' => '<',
@ -74,13 +74,11 @@ function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $s
// maybe a \0 byte or something is interfering?
// $source = trim( $source );
// capture html elements not to be messed with
$_offset = 0;
if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
foreach ($matches as $match) {
$store[] = $match[0][0];
$_length = strlen($match[0][0]);
$replace = array_shift($store);
$replace = $store[$match[1][0]];
$source = substr_replace($source, $replace, $match[0][1] + $_offset, $_length);
$_offset += strlen($replace) - $_length;
@ -90,5 +88,3 @@ function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $s
return $source;
}
?>

View file

@ -9,13 +9,14 @@
if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
/**
* escape_special_chars common function
*
* Function: smarty_function_escape_special_chars<br>
* Purpose: used by other smarty functions to escape
* special chars except for already escaped ones
*
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string text that should by escaped
*
* @return string
*/
function smarty_function_escape_special_chars($string)
@ -23,18 +24,20 @@ if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
if (!is_array($string)) {
$string = htmlspecialchars($string, ENT_COMPAT, Smarty::$_CHARSET, false);
}
return $string;
}
} else {
/**
* escape_special_chars common function
*
* Function: smarty_function_escape_special_chars<br>
* Purpose: used by other smarty functions to escape
* special chars except for already escaped ones
*
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param string $string text that should by escaped
*
* @return string
*/
function smarty_function_escape_special_chars($string)
@ -44,8 +47,7 @@ if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
$string = htmlspecialchars($string);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
}
return $string;
}
}
?>

View file

@ -12,6 +12,7 @@
* @param array $params parameter array as given to the compiler function
* @param integer $index array index of the parameter to convert
* @param mixed $default value to be returned if the parameter is not present
*
* @return mixed evaluated value of parameter or $default
* @throws SmartyException if parameter is not a literal (but an expression, variable, )
* @author Rodney Rehm
@ -23,11 +24,12 @@ function smarty_literal_compiler_param($params, $index, $default=null)
return $default;
}
// test if param is a literal
if (!preg_match('/^([\'"]?)[a-zA-Z0-9]+(\\1)$/', $params[$index])) {
if (!preg_match('/^([\'"]?)[a-zA-Z0-9-]+(\\1)$/', $params[$index])) {
throw new SmartyException('$param[' . $index . '] is not a literal and is thus not evaluatable at compile time');
}
$t = null;
eval("\$t = " . $params[$index] . ";");
return $t;
}

View file

@ -11,7 +11,9 @@
* Purpose: used by other smarty functions to make a timestamp from a string.
*
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param DateTime|int|string $string date object, timestamp or string that can be converted using strtotime()
*
* @return int
*/
function smarty_make_timestamp($string)
@ -19,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),
@ -35,8 +37,7 @@ function smarty_make_timestamp($string)
// strtotime() was not able to parse $string, use "now":
return time();
}
return $time;
}
}
?>

View file

@ -14,6 +14,7 @@ if (!function_exists('smarty_mb_str_replace')) {
* @param string $replace the replacement string
* @param string $subject the source string
* @param int &$count number of matches found
*
* @return string replaced string
* @author Rodney Rehm
*/
@ -48,8 +49,7 @@ if (!function_exists('smarty_mb_str_replace')) {
$count = count($parts) - 1;
$subject = implode($replace, $parts);
}
return $subject;
}
}
?>

View file

@ -10,17 +10,21 @@
* convert characters to their decimal unicode equivalents
*
* @link http://www.ibm.com/developerworks/library/os-php-unicode/index.html#listing3 for inspiration
*
* @param string $string characters to calculate unicode of
* @param string $encoding encoding of $string, if null mb_internal_encoding() is used
*
* @return array sequence of unicodes
* @author Rodney Rehm
*/
function smarty_mb_to_unicode($string, $encoding=null) {
function smarty_mb_to_unicode($string, $encoding = null)
{
if ($encoding) {
$expanded = mb_convert_encoding($string, "UTF-32BE", $encoding);
} else {
$expanded = mb_convert_encoding($string, "UTF-32BE");
}
return unpack("N*", $expanded);
}
@ -28,12 +32,15 @@ function smarty_mb_to_unicode($string, $encoding=null) {
* convert unicodes to the character of given encoding
*
* @link http://www.ibm.com/developerworks/library/os-php-unicode/index.html#listing3 for inspiration
*
* @param integer|array $unicode single unicode or list of unicodes to convert
* @param string $encoding encoding of returned string, if null mb_internal_encoding() is used
*
* @return string unicode as character sequence in given $encoding
* @author Rodney Rehm
*/
function smarty_mb_from_unicode($unicode, $encoding=null) {
function smarty_mb_from_unicode($unicode, $encoding = null)
{
$t = '';
if (!$encoding) {
$encoding = mb_internal_encoding();
@ -42,7 +49,6 @@ function smarty_mb_from_unicode($unicode, $encoding=null) {
$character = pack("N*", $utf32be);
$t .= mb_convert_encoding($character, $encoding, "UTF-32BE");
}
return $t;
}
?>

View file

@ -12,10 +12,12 @@ if(!function_exists('smarty_mb_wordwrap')) {
* Wrap a string to a given number of characters
*
* @link http://php.net/manual/en/function.wordwrap.php for similarity
*
* @param string $str the string to wrap
* @param int $width the width of the output
* @param string $break the character used to break the line
* @param boolean $cut ignored parameter, just for the sake of
*
* @return string wrapped string
* @author Rodney Rehm
*/
@ -26,20 +28,14 @@ if(!function_exists('smarty_mb_wordwrap')) {
$length = 0;
$t = '';
$_previous = false;
$_space = false;
foreach ($tokens as $_token) {
$token_length = mb_strlen($_token, Smarty::$_CHARSET);
$_tokens = array($_token);
if ($token_length > $width) {
// remove last space
$t = mb_substr($t, 0, -1, Smarty::$_CHARSET);
$_previous = false;
$length = 0;
if ($cut) {
$_tokens = preg_split('!(.{' . $width . '})!S' . Smarty::$_UTF8_MODIFIER, $_token, - 1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE);
// broken words go on a new line
$t .= $break;
}
}
@ -50,27 +46,23 @@ if(!function_exists('smarty_mb_wordwrap')) {
if ($length > $width) {
// remove space before inserted break
if ($_previous && $token_length < $width) {
if ($_previous) {
$t = mb_substr($t, 0, - 1, Smarty::$_CHARSET);
}
if (!$_space) {
// add the break before the token
if (!empty($t)) {
$t .= $break;
}
$length = $token_length;
// skip space after inserting a break
if ($_space) {
$length = 0;
continue;
}
} elseif ($token == "\n") {
// hard break must reset counters
$_previous = 0;
$length = 0;
} else {
// remember if we had a space or not
$_previous = $_space;
}
$_previous = $_space;
// add the token
$t .= $token;
}
@ -78,6 +70,4 @@ if(!function_exists('smarty_mb_wordwrap')) {
return $t;
}
}
?>

View file

@ -10,12 +10,10 @@
* Smarty htmlspecialchars variablefilter plugin
*
* @param string $source input string
* @param Smarty_Internal_Template $smarty Smarty object
*
* @return string filtered output
*/
function smarty_variablefilter_htmlspecialchars($source, $smarty)
function smarty_variablefilter_htmlspecialchars($source)
{
return htmlspecialchars($source, ENT_QUOTES, Smarty::$_CHARSET);
}
?>

View file

@ -13,69 +13,71 @@
* @subpackage Cacher
* @author Rodney Rehm
*/
abstract class Smarty_CacheResource {
/**
* cache for Smarty_CacheResource instances
* @var array
*/
public static $resources = array();
abstract class Smarty_CacheResource
{
/**
* 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
*
* @param Smarty_Template_Cached $cached cached object
* @param Smarty_Internal_Template $_template template object
*
* @return void
*/
public abstract function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template);
abstract public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template);
/**
* populate Cached Object with timestamp and exists from Resource
*
* @param Smarty_Template_Cached $source cached object
* @param Smarty_Template_Cached $cached
*
* @return void
*/
public abstract function populateTimestamp(Smarty_Template_Cached $cached);
abstract public function populateTimestamp(Smarty_Template_Cached $cached);
/**
* Read the cached template and process header
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if the cached content does not exist
* @param bool $update flag if called because cache update
*
* @return bool true or false if the cached content does not exist
*/
public abstract 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
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content to cache
*
* @return boolean success
*/
public abstract function writeCachedContent(Smarty_Internal_Template $_template, $content);
abstract public function writeCachedContent(Smarty_Internal_Template $_template, $content);
/**
* Return cached content
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content of cache
*
* @return null|string
*/
public function getCachedContent(Smarty_Internal_Template $_template)
{
if ($_template->cached->handler->process($_template)) {
ob_start();
$_template->properties['unifunc']($_template);
$unifunc = $_template->cached->unifunc;
$unifunc($_template);
return ob_get_clean();
}
return null;
}
@ -84,9 +86,10 @@ abstract class Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param integer $exp_time expiration time (number of seconds, not timestamp)
*
* @return integer number of cache files deleted
*/
public abstract function clearAll(Smarty $smarty, $exp_time=null);
abstract public function clearAll(Smarty $smarty, $exp_time = null);
/**
* Empty cache for a specific template
@ -96,11 +99,17 @@ abstract class Smarty_CacheResource {
* @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 abstract function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time);
abstract public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time);
/**
* @param Smarty $smarty
* @param Smarty_Template_Cached $cached
*
* @return bool|null
*/
public function locked(Smarty $smarty, Smarty_Template_Cached $cached)
{
// theoretically locking_timeout should be checked against time_limit (max_execution_time)
@ -114,33 +123,59 @@ abstract class Smarty_CacheResource {
}
sleep(1);
}
return $hadLock;
}
/**
* Check is cache is locked for this template
*
* @param Smarty $smarty
* @param Smarty_Template_Cached $cached
*
* @return bool
*/
public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
// check if lock exists
return false;
}
/**
* Lock cache for this template
*
* @param Smarty $smarty
* @param Smarty_Template_Cached $cached
*
* @return bool
*/
public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
// create lock
return true;
}
/**
* Unlock cache for this template
*
* @param Smarty $smarty
* @param Smarty_Template_Cached $cached
*
* @return bool
*/
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
// release lock
return true;
}
/**
* Load Cache Resource Handler
*
* @param Smarty $smarty Smarty object
* @param string $type name of the cache resource
*
* @throws SmartyException
* @return Smarty_CacheResource Cache Resource Handler
*/
public static function load(Smarty $smarty, $type = null)
@ -150,30 +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];
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}'");
@ -184,198 +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($smarty->_cache['template_objects'])) {
foreach ($smarty->_cache['template_objects'] as $key => $tpl) {
if (isset($tpl->cached)) {
$tpl->cached->valid = false;
$tpl->cached->processed = false;
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 Existance
* @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->timestamp = time();
$this->exists = true;
$this->valid = true;
if ($_template->smarty->cache_locking) {
$this->handler->releaseLock($_template->smarty, $this);
}
return true;
}
}
return false;
}
}
?>

View file

@ -13,8 +13,8 @@
* @subpackage Cacher
* @author Rodney Rehm
*/
abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource
{
/**
* fetch cached content and its modification time from data source
*
@ -24,13 +24,13 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
* @param string $compile_id compile id
* @param string $content cached content
* @param integer $mtime cache modification timestamp (epoch)
*
* @return void
*/
protected abstract function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime);
abstract protected function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime);
/**
* 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.}}
*
@ -38,6 +38,7 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
* @param string $name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
*
* @return integer|boolean timestamp (epoch) the template was modified, or false if not found
*/
protected function fetchTimestamp($id, $name, $cache_id, $compile_id)
@ -54,9 +55,10 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
* @param string $compile_id compile id
* @param integer|null $exp_time seconds till expiration or null
* @param string $content content to cache
*
* @return boolean success
*/
protected abstract function save($id, $name, $cache_id, $compile_id, $exp_time, $content);
abstract protected function save($id, $name, $cache_id, $compile_id, $exp_time, $content);
/**
* Delete content from cache
@ -65,30 +67,36 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer|null $exp_time seconds till expiration time in seconds or null
*
* @return integer number of deleted caches
*/
protected abstract function delete($name, $cache_id, $compile_id, $exp_time);
abstract protected function delete($name, $cache_id, $compile_id, $exp_time);
/**
* populate Cached Object with meta data from Resource
*
* @param Smarty_Template_Cached $cached cached object
* @param Smarty_Internal_Template $_template template object
*
* @return void
*/
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);
}
/**
* populate Cached Object with timestamp and exists from Resource
*
* @param Smarty_Template_Cached $source cached object
* @param Smarty_Template_Cached $cached
*
* @return void
*/
public function populateTimestamp(Smarty_Template_Cached $cached)
@ -97,6 +105,7 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
if ($mtime !== null) {
$cached->timestamp = $mtime;
$cached->exists = !!$cached->timestamp;
return;
}
$timestamp = null;
@ -110,9 +119,11 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if the cached content does not exist
* @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;
@ -120,20 +131,18 @@ 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
* used in evaluated code
*/
$_smarty_tpl = $_template;
eval("?>" . $content);
$cached->content = null;
return true;
}
return false;
}
@ -142,18 +151,33 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content to cache
*
* @return boolean success
*/
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;
}
/**
@ -161,11 +185,11 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param integer $exp_time expiration time (number of seconds, not timestamp)
*
* @return integer number of cache files deleted
*/
public function clearAll(Smarty $smarty, $exp_time = null)
{
$this->cache = array();
return $this->delete(null, null, null, $exp_time);
}
@ -177,12 +201,31 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
* @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 function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
{
$this->cache = array();
return $this->delete($resource_name, $cache_id, $compile_id, $exp_time);
$cache_name = null;
if (isset($resource_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 (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]);
}
}
}
}
return $this->delete($cache_name, $cache_id, $compile_id, $exp_time);
}
/**
@ -190,19 +233,19 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if cache is locked
*
* @return boolean true or false if cache is locked
*/
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;
}
/**
@ -210,14 +253,15 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*
* @return bool|void
*/
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, '');
}
/**
@ -225,13 +269,13 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*
* @return bool|void
*/
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);
}
}
?>

View file

@ -8,19 +8,16 @@
/**
* Smarty Cache Handler Base for Key/Value Storage Implementations
*
* This class implements the functionality required to use simple key/value stores
* for hierarchical cache groups. key/value stores like memcache or APC do not support
* wildcards in keys, therefore a cache group cannot be cleared like "a|*" - which
* is no problem to filesystem and RDBMS implementations.
*
* This implementation is based on the concept of invalidation. While one specific cache
* can be identified and cleared, any range of caches cannot be identified. For this reason
* each level of the cache group hierarchy can have its own value in the store. These values
* are nothing but microtimes, telling us when a particular cache group was cleared for the
* last time. These keys are evaluated for every cache read to determine if the cache has
* been invalidated since it was created and should hence be treated as inexistent.
*
* Although deep hierarchies are possible, they are not recommended. Try to keep your
* cache groups as shallow as possible. Anything up 3-5 parents should be ok. So
* »a|b| is a good depth where »a|b|c|d|e|f|g|h|i|j| isn't. Try to join correlating
@ -31,15 +28,18 @@
* @subpackage Cacher
* @author Rodney Rehm
*/
abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource
{
/**
* cache for contents
*
* @var array
*/
protected $contents = array();
/**
* cache for timestamps
*
* @var array
*/
protected $timestamps = array();
@ -49,14 +49,13 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
*
* @param Smarty_Template_Cached $cached cached object
* @param Smarty_Internal_Template $_template template object
*
* @return void
*/
public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
{
$cached->filepath = $_template->source->uid
. '#' . $this->sanitize($cached->source->name)
. '#' . $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);
}
@ -65,6 +64,7 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
* populate Cached Object with timestamp and exists from Resource
*
* @param Smarty_Template_Cached $cached cached object
*
* @return void
*/
public function populateTimestamp(Smarty_Template_Cached $cached)
@ -82,9 +82,11 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if the cached content does not exist
* @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;
@ -97,10 +99,15 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
}
}
if (isset($content)) {
/** @var Smarty_Internal_Template $_smarty_tpl
* used in evaluated code
*/
$_smarty_tpl = $_template;
eval("?>" . $content);
return true;
}
return false;
}
@ -109,21 +116,45 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content to cache
*
* @return boolean success
*/
public function writeCachedContent(Smarty_Internal_Template $_template, $content)
{
$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;
}
/**
* Empty cache
*
* {@internal the $exp_time argument is ignored altogether }}
*
* @param Smarty $smarty Smarty object
* @param integer $exp_time expiration time [being ignored]
*
* @return integer number of cache files deleted [always -1]
* @uses purge() to clear the whole store
* @uses invalidate() to mark everything outdated if purge() is inapplicable
@ -133,12 +164,19 @@ 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;
}
/**
* Empty cache for a specific template
*
* {@internal the $exp_time argument is ignored altogether}}
*
* @param Smarty $smarty Smarty object
@ -146,6 +184,7 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer $exp_time expiration time [being ignored]
*
* @return integer number of cache files deleted [always -1]
* @uses buildCachedFilepath() to generate the CacheID
* @uses invalidate() to mark CacheIDs parent chain as outdated
@ -153,53 +192,54 @@ 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;
}
/**
* Get template's unique ID
*
* @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 '';
}
/**
* Sanitize CacheID components
*
* @param string $string CacheID component to sanitize
*
* @return string sanitized CacheID component
*/
protected function sanitize($string)
{
// some poeple smoke bad weed
$string = trim($string, '|');
if (!$string) {
return null;
@ -217,6 +257,7 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
* @param string $content cached content
* @param integer &$timestamp cached timestamp (epoch)
* @param string $resource_uid resource's uid
*
* @return boolean success
*/
protected function fetch($cid, $resource_name = null, $cache_id = null, $compile_id = null, &$content = null, &$timestamp = null, $resource_uid = null)
@ -238,7 +279,6 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
/**
* Add current microtime to the beginning of $cache_content
*
* {@internal the header uses 8 Bytes, the first 4 Bytes are the seconds, the second 4 Bytes are the microseconds}}
*
* @param string &$content the content to be cached
@ -254,14 +294,13 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
* Extract the timestamp the $content was cached
*
* @param string &$content the cached content
*
* @return float the microtime the content was cached
*/
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);
}
/**
@ -272,6 +311,7 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param string $resource_uid source's uid
*
* @return void
*/
protected function invalidate($cid = null, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null)
@ -281,23 +321,25 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
// invalidate everything
if (!$resource_name && !$cache_id && !$compile_id) {
$key = 'IVK#ALL';
}
// invalidate all caches by template
else if ($resource_name && !$cache_id && !$compile_id) {
} // invalidate all caches by template
else {
if ($resource_name && !$cache_id && !$compile_id) {
$key = 'IVK#TEMPLATE#' . $resource_uid . '#' . $this->sanitize($resource_name);
}
// invalidate all caches by cache group
else if (!$resource_name && $cache_id && !$compile_id) {
} // invalidate all caches by cache group
else {
if (!$resource_name && $cache_id && !$compile_id) {
$key = 'IVK#CACHE#' . $this->sanitize($cache_id);
}
// invalidate all caches by compile id
else if (!$resource_name && !$cache_id && $compile_id) {
} // invalidate all caches by compile id
else {
if (!$resource_name && !$cache_id && $compile_id) {
$key = 'IVK#COMPILE#' . $this->sanitize($compile_id);
}
// invalidate by combination
} // invalidate by combination
else {
$key = 'IVK#CID#' . $cid;
}
}
}
}
$this->write(array($key => $now));
}
@ -309,6 +351,7 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param string $resource_uid source's filepath
*
* @return float the microtime the CacheID was invalidated
*/
protected function getLatestInvalidationTimestamp($cid, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null)
@ -328,12 +371,12 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
}
// make sure we're dealing with floats
$values = array_map('floatval', $values);
return max($values);
}
/**
* Translate a CacheID into the list of applicable InvalidationKeys.
*
* Splits "some|chain|into|an|array" into array( '#clearAll#', 'some', 'some|chain', 'some|chain|into', ... )
*
* @param string $cid CacheID to translate
@ -341,6 +384,7 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param string $resource_uid source's filepath
*
* @return array list of InvalidationKeys
* @uses $invalidationKeyPrefix to prepend to each InvalidationKey
*/
@ -357,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;
@ -380,6 +423,7 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
// skip past delimiter position
$i ++;
}
return $t;
}
@ -388,12 +432,14 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if cache is locked
*
* @return boolean true or false if cache is locked
*/
public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$key = 'LOCK#' . $cached->filepath;
$data = $this->read(array($key));
return $data && time() - $data[$key] < $smarty->locking_timeout;
}
@ -402,6 +448,8 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*
* @return bool|void
*/
public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
@ -415,6 +463,8 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*
* @return bool|void
*/
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
@ -427,26 +477,29 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
* Read values for a set of keys from cache
*
* @param array $keys list of keys to fetch
*
* @return array list of values with the given keys used as indexes
*/
protected abstract function read(array $keys);
abstract protected function read(array $keys);
/**
* Save values for a set of keys to cache
*
* @param array $keys list of values to save
* @param int $expire expiration time
*
* @return boolean true on success, false on failure
*/
protected abstract function write(array $keys, $expire=null);
abstract protected function write(array $keys, $expire = null);
/**
* Remove values from cache
*
* @param array $keys list of keys to delete
*
* @return boolean true on success, false on failure
*/
protected abstract function delete(array $keys);
abstract protected function delete(array $keys);
/**
* Remove *all* values from cache
@ -457,7 +510,4 @@ abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource {
{
return false;
}
}
?>

View file

@ -1,95 +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
* @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.");
}
}
}
?>

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");
}
}
}

View file

@ -10,33 +10,31 @@
/**
* This class does contain all necessary methods for the HTML cache on file system
*
* Implements the file system as resource for the HTML cache Version ussing nocache inserts.
*
* @package Smarty
* @subpackage Cacher
*/
class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
class Smarty_Internal_CacheResource_File extends Smarty_CacheResource
{
/**
* populate Cached Object with meta data from Resource
*
* @param Smarty_Template_Cached $cached cached object
* @param Smarty_Internal_Template $_template template object
*
* @return void
*/
public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
{
$_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,21 +58,27 @@ 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);
}
}
/**
* populate Cached Object with timestamp and exists from Resource
*
* @param Smarty_Template_Cached $cached cached object
*
* @return void
*/
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);
}
}
/**
@ -82,27 +86,42 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
*
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if the cached content does not exist
* @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)
{
/** @var Smarty_Internal_Template $_smarty_tpl
* used in included file
*/
$_smarty_tpl = $_template;
$_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;
}
}
/**
* Write the rendered template output to cache
*
* @param Smarty_Internal_Template $_template template object
* @param string $content content to cache
*
* @return boolean success
*/
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;
}
}
@ -110,114 +129,47 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
}
/**
* Empty cache
* 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;
}
/**
* Empty cache
*
* @param Smarty $smarty
* @param integer $exp_time expiration time (number of seconds, not timestamp)
*
* @return integer number of cache files deleted
*/
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);
}
/**
* Empty cache for a specific template
*
* @param Smarty $_template template object
* @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 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();
$_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) && $_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);
}
/**
@ -225,7 +177,8 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
* @return booelan true or false if cache is locked
*
* @return boolean true or false if cache is locked
*/
public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
@ -234,8 +187,12 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
} else {
clearstatcache();
}
if (is_file($cached->lock_id)) {
$t = @filemtime($cached->lock_id);
return $t && (time() - $t < $smarty->locking_timeout);
} else {
return false;
}
}
/**
@ -243,6 +200,8 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*
* @return bool|void
*/
public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
@ -255,6 +214,8 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
*
* @param Smarty $smarty Smarty object
* @param Smarty_Template_Cached $cached cached object
*
* @return bool|void
*/
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
@ -262,5 +223,3 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
@unlink($cached->lock_id);
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Append
*
* Compiles the {append} tag
*
* @package Smarty
@ -15,17 +14,18 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Append extends Smarty_Internal_Compile_Assign {
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 \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');
@ -47,7 +47,4 @@ class Smarty_Internal_Compile_Append extends Smarty_Internal_Compile_Assign {
// call compile assign
return parent::compile($_new_attr, $compiler, $_params);
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Assign
*
* Compiles the {assign} tag
*
* @package Smarty
@ -15,24 +14,33 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase {
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 \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,47 +50,49 @@ 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 (!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;
} else {
$compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno);
} 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;
}
}
?>

View file

@ -1,23 +1,20 @@
<?php
/**
* Smarty Internal Plugin Compile Block
/*
* This file is part of Smarty.
*
* Compiles the {block}{/block} tags
* (c) 2015 Uwe Tews
*
* @package Smarty
* @subpackage Compiler
* @author 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
{
/**
* Attribute definition: Overwrites base class.
*
@ -32,7 +29,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name', 'hide');
public $shorttag_order = array('name');
/**
* Attribute definition: Overwrites base class.
@ -40,243 +37,256 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('hide');
public $option_flags = array('hide', 'nocache');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('assign');
/**
* nesting level of block tags
*
* @var int
*/
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
* @return boolean true
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @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);
$save = array($_attr, $compiler->parser->current_buffer, $compiler->nocache, $compiler->smarty->merge_compiled_includes, $compiler->merged_templates, $compiler->smarty->merged_templates_func, $compiler->template->properties, $compiler->template->has_nocache_code);
$this->openTag($compiler, 'block', $save);
if ($_attr['nocache'] == true) {
$compiler->nocache = true;
}
// set flag for {block} tag
$compiler->inheritance = true;
// must merge includes
$compiler->smarty->merge_compiled_includes = true;
$compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
$compiler->has_code = false;
return true;
}
/**
* Save or replace child block source by block name during parsing
*
* @param string $block_content block source content
* @param string $block_tag opening block tag
* @param object $template template object
* @param string $filepath filepath of template source
*/
public static function saveBlockData($block_content, $block_tag, $template, $filepath) {
$_rdl = preg_quote($template->smarty->right_delimiter);
$_ldl = preg_quote($template->smarty->left_delimiter);
if (!$template->smarty->auto_literal) {
$al = '\s*';
} else {
$al = '';
}
if (0 == preg_match("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")(\s*?)?((append|prepend|nocache)?(\s*)?(hide)?)?(\s*{$_rdl})!", $block_tag, $_match)) {
$error_text = 'Syntax Error in template "' . $template->source->filepath . '" "' . htmlspecialchars($block_tag) . '" illegal options';
throw new SmartyCompilerException($error_text);
} else {
$_name = trim($_match[3], '\'"');
if ($_match[8] != 'hide' || isset($template->block_data[$_name])) { // replace {$smarty.block.child}
// get nested block tags
if (0 != preg_match_all("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")([\s\S]*?)(hide)?(\s*{$_rdl})([\s\S]*?)(.*)?({$_ldl}{$al}/block\s*{$_rdl})!", $block_content, $_match2)) {
foreach ($_match2[3] as $key => $name) {
// get it's replacement
$_name2 = trim($name, '\'"');
if ($_match2[5][$key] != 'hide' || isset($template->block_data[$_name2])) {
if (isset($template->block_data[$_name2])) {
$replacement = $template->block_data[$_name2]['source'];
} else {
$replacement = '';
}
// replace {$smarty.block.child} tag
if (preg_match("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!",$_match2[7][$key])) {
$replacement = preg_replace("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $replacement, $_match2[7][$key]);
$block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl}[\s\S]*?{$_ldl}{$al}/block\s*{$_rdl}))!", $replacement, $block_content);
}
if (preg_match("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!",$_match2[8][$key])) {
$replacement = preg_replace("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!", $replacement, $_match2[8][$key]);
$block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl})(.*)?({$_ldl}{$al}/block\s*{$_rdl}))!", $replacement, $block_content);
}
} else {
// remove hidden blocks
$block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl}[\s\S]*?{$_ldl}{$al}/block\s*{$_rdl}))!", '', $block_content);
}
}
}
// do we have not nested {$smart.block.child}
if (0 != preg_match("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $block_content, $_match2)) {
// get child replacement for this block
if (isset($template->block_data[$_name])) {
$replacement = $template->block_data[$_name]['source'];
unset($template->block_data[$_name]);
} else {
$replacement = '';
}
$block_content = preg_replace("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $replacement, $block_content);
}
if (isset($template->block_data[$_name])) {
if (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
$template->block_data[$_name]['source'] =
str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $template->block_data[$_name]['source']);
} elseif ($template->block_data[$_name]['mode'] == 'prepend') {
$template->block_data[$_name]['source'] .= $block_content;
} elseif ($template->block_data[$_name]['mode'] == 'append') {
$template->block_data[$_name]['source'] = $block_content . $template->block_data[$_name]['source'];
}
} else {
$template->block_data[$_name]['source'] = $block_content;
$template->block_data[$_name]['file'] = $filepath;
}
if ($_match[6] == 'append') {
$template->block_data[$_name]['mode'] = 'append';
} elseif ($_match[6] == 'prepend') {
$template->block_data[$_name]['mode'] = 'prepend';
} else {
$template->block_data[$_name]['mode'] = 'replace';
}
$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;
}
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
// $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 \Smarty_Internal_TemplateCompilerBase compiler object
* @param string $_name optional name of child block
* @return string compiled code of schild block
*
* @return string compiled code of child block
*/
public static function compileChildBlock($compiler, $_name = null) {
$_output = '';
// 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;
static function compileChildBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
{
if (!isset($compiler->_cache['blockNesting'])) {
$compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ',
$compiler->parser->lex->taglineno);
}
}
// flag that child is already compile by {$smarty.block.child} inclusion
$compiler->template->block_data[$_name]['compiled'] = true;
}
if ($_name == null) {
$compiler->trigger_template_error('{$smarty.block.child} used out of context', $compiler->lex->taglineno);
}
// undefined child?
if (!isset($compiler->template->block_data[$_name]['source'])) {
return '';
}
$_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
$compiler->template->compile_id = null, $compiler->template->caching, $compiler->template->cache_lifetime);
$_tpl->variable_filters = $compiler->template->variable_filters;
$_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
$_tpl->source->filepath = $compiler->template->block_data[$_name]['file'];
$_tpl->allow_relative_path = true;
if ($compiler->nocache) {
$_tpl->compiler->forceNocache = 2;
} else {
$_tpl->compiler->forceNocache = 1;
}
$_tpl->compiler->suppressHeader = true;
$_tpl->compiler->suppressTemplatePropertyHeader = true;
$_tpl->compiler->suppressMergedTemplates = true;
if (strpos($compiler->template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
$_output = str_replace('%%%%SMARTY_PARENT%%%%', $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl));
} elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') {
$_output = $_tpl->compiler->compileTemplate($_tpl) . $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);
} elseif (!empty($compiler->template->block_data[$_name])) {
$_output = $_tpl->compiler->compileTemplate($_tpl);
}
$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);
return $_output;
$compiler->has_code = true;
$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 \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param string $_name optional name of child block
*
* @return string compiled code of child block
*/
static function compileParentBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
{
if (!isset($compiler->_cache['blockNesting'])) {
$compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ',
$compiler->parser->lex->taglineno);
}
$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
* @return string compiled code
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @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'], "\"'");
if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
// restore to status before {block} tag as new subtemplate code of parent {block} is not needed
// TODO: Below code was disabled in 3.1.8 because of problems with {include} in nested {block} tags in child templates
// combined with append/prepend or $smarty.block.parent
// For later versions it should be checked under which conditions it could run for optimisation
//
//$compiler->merged_templates = $saved_data[4];
//$compiler->smarty->merged_templates_func = $saved_data[5];
//$compiler->template->properties = $saved_data[6];
//$compiler->template->has_nocache_code = $saved_data[7];
$_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
} else {
if (isset($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[1];
$compiler->nocache = $saved_data[2];
$compiler->smarty->merge_compiled_includes = $saved_data[3];
// reset flag for {block} tag
$compiler->inheritance = false;
// $_output content has already nocache code processed
$compiler->suppressNocacheProcessing = true;
return $_output;
return $output;
}
/**
* @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;
}
}
?>

View file

@ -1,21 +1,21 @@
<?php
/**
* Smarty Internal Plugin Compile Break
*
* Compiles the {break} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Break Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -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.
*
@ -35,23 +36,25 @@ 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 \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 {
@ -66,12 +69,9 @@ 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->has_code = true;
return "<?php break {$_levels}?>";
$compiler->trigger_template_error("cannot break {$_levels} level(s)", null, true);
}
return "<?php break {$_levels};?>";
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Function_Call
*
* Compiles the calls of user defined tags defined by {function}
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -24,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.
*
@ -31,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.
*
@ -44,7 +45,7 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase {
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
*/
public function compile($args, $compiler)
@ -53,16 +54,14 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase {
$_attr = $this->getAttributes($compiler, $args);
// save possible attributes
if (isset($_attr['assign'])) {
// output will be stored in a smarty variable instead of beind displayed
// 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';
@ -75,56 +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";
}
}
}
}
//varibale 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";
$_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 {
$_output = "<?php ob_start(); {$call_function}(\$_smarty_tpl,{$_params}); \$_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;
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Capture
*
* Compiles the {capture} tag
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -24,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.
*
@ -36,10 +36,11 @@ 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 \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,11 +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";
}
}
/**
@ -64,16 +85,17 @@ class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase {
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_CaptureClose extends Smarty_Internal_CompileBase {
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 \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,15 +106,13 @@ 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;
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Config Load
*
* Compiles the {config load} tag
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -24,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.
*
@ -31,55 +31,74 @@ 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 \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 posible attributes
// save possible attributes
$conf_file = $_attr['file'];
if (isset($_attr['section'])) {
$section = $_attr['section'];
} 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;
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Continue
*
* Compiles the {continue} tag
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -24,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.
*
@ -36,23 +36,25 @@ 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 \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,12 +69,9 @@ 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->has_code = true;
return "<?php continue {$_levels}?>";
$compiler->trigger_template_error("cannot continue {$_levels} level(s)", null, true);
}
return "<?php continue {$_levels};?>";
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Debug
*
* Compiles the {debug} tag.
* It opens a window the the Smarty Debugging Console.
*
@ -16,13 +15,14 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Debug extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Debug extends Smarty_Internal_CompileBase
{
/**
* Compiles code for the {debug} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
*
* @return string compiled code
*/
public function compile($args, $compiler)
@ -34,10 +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;
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Eval
*
* Compiles the {eval} tag.
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Eval extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Eval extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -44,6 +43,7 @@ class Smarty_Internal_Compile_Eval extends Smarty_Internal_CompileBase {
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
*
* @return string compiled code
*/
public function compile($args, $compiler)
@ -53,7 +53,7 @@ class Smarty_Internal_Compile_Eval extends Smarty_Internal_CompileBase {
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if (isset($_attr['assign'])) {
// output will be stored in a smarty variable instead of beind displayed
// output will be stored in a smarty variable instead of being displayed
$_assign = $_attr['assign'];
}
@ -65,9 +65,7 @@ class Smarty_Internal_Compile_Eval extends Smarty_Internal_CompileBase {
} else {
$_output .= "echo \$_template->fetch();";
}
return "<?php $_output ?>";
}
}
?>

View file

@ -2,7 +2,6 @@
/**
* Smarty Internal Plugin Compile extend
*
* Compiles the {extends} tag
*
* @package Smarty
@ -16,8 +15,8 @@
* @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.
*
@ -25,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.
*
@ -32,102 +40,95 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('file');
/**
* mbstring.overload flag
*
* @var int
*/
public $mbstring_overload = 0;
/**
* 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 \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)
{
static $_is_stringy = array('string' => true, 'eval' => true);
$this->_rdl = preg_quote($compiler->smarty->right_delimiter);
$this->_ldl = preg_quote($compiler->smarty->left_delimiter);
if (!$compiler->smarty->auto_literal) {
$al = '\s*';
} else {
$al = '';
}
$filepath = $compiler->template->source->filepath;
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
// 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);
}
$_smarty_tpl = $compiler->template;
$include_file = null;
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);
}
eval('$include_file = ' . $_attr['file'] . ';');
// create template object
$_template = new $compiler->smarty->template_class($include_file, $compiler->smarty, $compiler->template);
// save file dependency
if (isset($_is_stringy[$_template->source->type])) {
$template_sha1 = sha1($include_file);
// 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 {
$template_sha1 = sha1($_template->source->filepath);
$file = "'{$file}'";
}
if (isset($compiler->template->properties['file_dependency'][$template_sha1])) {
$compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"", $compiler->lex->line - 1);
$i ++;
if ($i == count($files) && isset($_attr['extends_resource'])) {
$this->compileEndChild($compiler);
}
$compiler->template->properties['file_dependency'][$template_sha1] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type);
$_content = ($this->mbstring_overload ? mb_substr($compiler->lex->data, $compiler->lex->counter - 1, 20000000, 'latin1') : substr($compiler->lex->data, $compiler->lex->counter - 1));
if (preg_match_all("!({$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl})!", $_content, $s) !=
preg_match_all("!({$this->_ldl}{$al}/block\s*{$this->_rdl})!", $_content, $c)) {
$compiler->trigger_template_error('unmatched {block} {/block} pairs');
$this->compileInclude($compiler, $file);
}
preg_match_all("!{$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl}|{$this->_ldl}{$al}/block\s*{$this->_rdl}|{$this->_ldl}\*([\S\s]*?)\*{$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
$_result_count = count($_result[0]);
$_start = 0;
while ($_start+1 < $_result_count) {
$_end = 0;
$_level = 1;
if (($this->mbstring_overload ? mb_substr($_result[0][$_start][0],0,mb_strlen($compiler->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start][0],0,strlen($compiler->smarty->left_delimiter)+1)) == $compiler->smarty->left_delimiter.'*') {
$_start++;
continue;
if (!isset($_attr['extends_resource'])) {
$this->compileEndChild($compiler);
}
while ($_level != 0) {
$_end++;
if (($this->mbstring_overload ? mb_substr($_result[0][$_start + $_end][0],0,mb_strlen($compiler->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start + $_end][0],0,strlen($compiler->smarty->left_delimiter)+1)) == $compiler->smarty->left_delimiter.'*') {
continue;
}
if (!strpos($_result[0][$_start + $_end][0], '/')) {
$_level++;
} else {
$_level--;
$this->compileEndChild($compiler);
$this->compileInclude($compiler, $_attr['file']);
}
}
$_block_content = str_replace($compiler->smarty->left_delimiter . '$smarty.block.parent' . $compiler->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%',
($this->mbstring_overload ? mb_substr($_content, $_result[0][$_start][1] + mb_strlen($_result[0][$_start][0], 'latin1'), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + mb_strlen($_result[0][$_start][0], 'latin1'), 'latin1') : substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0]))));
Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $compiler->template, $filepath);
$_start = $_start + $_end + 1;
}
if ($_template->source->type == 'extends') {
$_template->block_data = $compiler->template->block_data;
}
$compiler->template->source->content = $_template->source->content;
if ($_template->source->type == 'extends') {
$compiler->template->block_data = $_template->block_data;
foreach ($_template->source->components as $key => $component) {
$compiler->template->properties['file_dependency'][$key] = array($component->filepath, $component->timestamp, $component->type);
}
}
$compiler->template->source->filepath = $_template->source->filepath;
$compiler->abort_and_recompile = true;
$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}';
}
}

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile For
*
* Compiles the {for} {forelse} {/for} tags
*
* @package Smarty
@ -15,29 +14,27 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase
{
/**
* Compiles code for the {for} tag
*
* Smarty 3 does implement two different sytaxes:
*
* Smarty 3 does implement two different syntax's:
* - {for $var in $array}
* For looping over arrays or iterators
*
* - {for $x=0; $x<$y; $x++}
* For general loops
*
* The parser is gereration different sets of attribute by which this compiler can
* determin which syntax is used.
* The parser is generating different sets of attribute by which this compiler can
* determine which syntax is used.
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
$compiler->loopNesting++;
if ($parameter == 0) {
$this->required_attributes = array('start', 'to');
$this->optional_attributes = array('max', 'step');
@ -48,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 .= " if ($_attr[ifexp]){ for (\$_foo=true;$_attr[ifexp]; \$_smarty_tpl->tpl_vars[$_attr[var]]->value$_attr[step]){\n";
$output .= "\$_smarty_tpl->tpl_vars[$var] = new Smarty_Variable;\n";
$output .= "\$_smarty_tpl->tpl_vars[$var]->value{$index} = {$_statement['value']};\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 .= "?>";
@ -81,7 +99,6 @@ class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase {
// return compiled code
return $output;
}
}
/**
@ -90,14 +107,15 @@ class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase {
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Forelse extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Forelse extends Smarty_Internal_CompileBase
{
/**
* Compiles code for the {forelse} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
@ -107,9 +125,9 @@ class Smarty_Internal_Compile_Forelse extends Smarty_Internal_CompileBase {
list($openTag, $nocache) = $this->closeTag($compiler, array('for'));
$this->openTag($compiler, 'forelse', array('forelse', $nocache));
return "<?php }} else { ?>";
}
}
/**
@ -118,18 +136,20 @@ class Smarty_Internal_Compile_Forelse extends Smarty_Internal_CompileBase {
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Forclose extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Forclose extends Smarty_Internal_CompileBase
{
/**
* Compiles code for the {/for} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param array $parameter array with compilation parameter
*
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
$compiler->loopNesting--;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// must endblock be nocache?
@ -139,13 +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;
}
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Foreach
*
* Compiles the {foreach} {foreachelse} {/foreach} tags
*
* @package Smarty
@ -15,7 +14,8 @@
* @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 \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)
{
$tpl = $compiler->template;
$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($tpl->source->content, $SmartyVarName . 'first') !== false;
$usesSmartyLast = strpos($tpl->source->content, $SmartyVarName . 'last') !== false;
$usesSmartyIndex = strpos($tpl->source->content, $SmartyVarName . 'index') !== false;
$usesSmartyIteration = strpos($tpl->source->content, $SmartyVarName . 'iteration') !== false;
$usesSmartyShow = strpos($tpl->source->content, $SmartyVarName . 'show') !== false;
$usesSmartyTotal = strpos($tpl->source->content, $SmartyVarName . 'total') !== false;
} else {
$usesSmartyFirst = false;
$usesSmartyLast = false;
$usesSmartyTotal = false;
$usesSmartyShow = false;
}
$usesPropFirst = $usesSmartyFirst || strpos($tpl->source->content, $ItemVarName . 'first') !== false;
$usesPropLast = $usesSmartyLast || strpos($tpl->source->content, $ItemVarName . 'last') !== false;
$usesPropIndex = $usesPropFirst || strpos($tpl->source->content, $ItemVarName . 'index') !== false;
$usesPropIteration = $usesPropLast || strpos($tpl->source->content, $ItemVarName . 'iteration') !== false;
$usesPropShow = strpos($tpl->source->content, $ItemVarName . 'show') !== false;
$usesPropTotal = $usesSmartyTotal || $usesSmartyShow || $usesPropShow || $usesPropLast || strpos($tpl->source->content, $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 ($this->isNamed) {
$prop = array();
if (isset($namedAttr['total'])) {
$prop['total'] = "'total' => {$local}total";
}
if ($usesPropShow) {
$output .= " \$_smarty_tpl->tpl_vars[$item]->show = (\$_smarty_tpl->tpl_vars[$item]->total > 0);\n";
if (isset($namedAttr['iteration'])) {
$prop['iteration'] = "'iteration' => 0";
}
if ($has_name) {
if ($usesSmartyTotal) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['total'] = \$_smarty_tpl->tpl_vars[$item]->total;\n";
if (isset($namedAttr['index'])) {
$prop['index'] = "'index' => -1";
}
if ($usesSmartyIteration) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']=0;\n";
if (isset($namedAttr['show'])) {
$prop['show'] = "'show' => ({$local}total > 0)";
}
if ($usesSmartyIndex) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']=-1;\n";
}
if ($usesSmartyShow) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['show']=(\$_smarty_tpl->tpl_vars[$item]->total > 0);\n";
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 ($usesSmartyIteration) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']++;\n";
if (isset($itemAttr['iteration'])) {
$output .= "{$itemVar}->iteration++;\n";
}
if ($usesSmartyIndex) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']++;\n";
if (isset($itemAttr['index'])) {
$output .= "{$itemVar}->index++;\n";
}
if ($usesSmartyLast) {
$output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['last'] = \$_smarty_tpl->tpl_vars[$item]->last;\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 (isset($namedAttr['index'])) {
$output .= "{$foreachVar}->value['index']++;\n";
}
if (isset($namedAttr['first'])) {
$output .= "{$foreachVar}->value['first'] = {$local}first;\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;
@ -173,27 +275,30 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_CompileBase {
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase {
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 \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;
}
}
/**
@ -202,30 +307,39 @@ class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase {
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase {
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 \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;
}
}

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Function
*
* Compiles the {function} {/function} tags
*
* @package Smarty
@ -15,7 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
@ -24,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.
*
@ -31,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.
*
@ -43,52 +45,32 @@ 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 \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();
$_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);}?>";
}
// Init temporay 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->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->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
$compiler->template->compiled->has_nocache_code = false;
return true;
}
}
/**
@ -97,70 +79,132 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase {
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Functionclose 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 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";
}
}
$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";
}
// remove last line break from function definition
$last = count($compiler->parser->current_buffer->subtrees) - 1;
if ($compiler->parser->current_buffer->subtrees[$last] instanceof _smarty_linebreak) {
unset($compiler->parser->current_buffer->subtrees[$last]);
}
// 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;
$_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();
$compiler->smarty->template_functions[$_name] = $compiler->template->properties['function'][$_name];
$compiler->has_code = false;
$output = true;
$_parameter = $_attr;
unset($_parameter['name']);
// default parameter
$_paramsArray = array();
foreach ($_parameter as $_key => $_value) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} 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";
$_paramsArray[] = "'$_key'=>$_value";
}
// reset flag that we are compiling a template function
$compiler->compiles_template_function = false;
// restore old compiler status
}
if (!empty($_paramsArray)) {
$_params = 'array(' . implode(",", $_paramsArray) . ')';
$_paramsCode = "\$params = array_merge($_params, \$params);\n";
} else {
$_paramsCode = '';
}
$_functionCode = $compiler->parser->current_buffer;
// setup buffer for template function code
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
$_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];
$compiler->template->has_nocache_code = $compiler->template->has_nocache_code | $saved_data[2];
$compiler->template->required_plugins = $saved_data[3];
return $output;
// 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;
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile If
*
* Compiles the {if} {else} {elseif} {/if} tags
*
* @package Smarty
@ -15,17 +14,19 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase {
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 \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,26 +43,39 @@ 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;
} else {
return "<?php if ({$parameter['if condition']}) {?>";
}
}
}
/**
@ -70,24 +84,24 @@ class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase {
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Else extends Smarty_Internal_CompileBase {
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 \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));
return "<?php } else { ?>";
}
}
/**
@ -96,17 +110,19 @@ class Smarty_Internal_Compile_Else extends Smarty_Internal_CompileBase {
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase {
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 \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);
@ -114,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'])) {
@ -123,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 = '';
@ -138,38 +159,63 @@ 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;
} else {
$this->openTag($compiler, 'elseif', array($nesting, $compiler->tag_nocache));
return "<?php } elseif ({$parameter['if condition']}) {?>";
}
} else {
$tmp = '';
foreach ($compiler->prefix_code as $code)
$tmp .= $code;
foreach ($compiler->prefix_code as $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'] . "){?>";
}
return $_output;
} else {
return "<?php }else{?>{$tmp}<?php if ({$parameter['if condition']}){?>";
}
}
$_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 $compiler->appendCode($tmp, "<?php if ({$parameter['if condition']}) {?>");
}
}
}
}
/**
@ -178,17 +224,18 @@ class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase {
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Ifclose extends Smarty_Internal_CompileBase {
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 \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) {
@ -199,9 +246,7 @@ class Smarty_Internal_Compile_Ifclose extends Smarty_Internal_CompileBase {
for ($i = 0; $i < $nesting; $i ++) {
$tmp .= '}';
}
return "<?php {$tmp}?>";
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Include
*
* Compiles the {include} tag
*
* @package Smarty
@ -15,12 +14,13 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
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.
*
@ -28,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.
*
@ -35,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.
*
@ -50,61 +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 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 posible 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 beind displayed
// 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 (!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') {
$_parent_scope = Smarty::SCOPE_PARENT;
$_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr['scope'] == 'root') {
$_parent_scope = Smarty::SCOPE_ROOT;
$_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr['scope'] == 'global') {
$_parent_scope = Smarty::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;
}
}
$_caching = 'null';
if ($compiler->nocache || $compiler->tag_nocache) {
}
// 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;
if ($_attr['nocache'] === true) {
$compiler->tag_nocache = true;
}
// default for included templates
$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';
}
@ -113,103 +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;
$_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 (($compiler->smarty->merge_compiled_includes || $_attr['inline'] === true) && !$compiler->template->source->recompiled
&& !($compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache)) && $_caching != Smarty::CACHING_LIFETIME_CURRENT) {
// check if compiled code can be merged (contains no variable part)
if (!$compiler->has_variable_string && (substr_count($include_file, '"') == 2 or substr_count($include_file, "'") == 2)
and substr_count($include_file, '(') == 0 and substr_count($include_file, '$_smarty_tpl->') == 0) {
$tpl_name = null;
eval("\$tpl_name = $include_file;");
if (!isset($compiler->smarty->merged_templates_func[$tpl_name]) || $compiler->inheritance) {
$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]['func'] = $tpl->properties['unifunc'] = 'content_'. str_replace('.', '_', uniqid('', true));
// use current nocache hash for inlined code
$compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash'] = $tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
if ($compiler->template->caching) {
// needs code for cached page but no cache file
$tpl->caching = self::CACHING_NOCACHE_CODE;
}
// make sure whole chain gest compiled
$tpl->mustCompile = true;
if (!($tpl->source->uncompiled) && $tpl->source->exists) {
// get compiled code
$compiled_code = $tpl->compiler->compileTemplate($tpl);
// 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;
}
if ($merge_compiled_includes) {
$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
foreach ($_attr as $key => $value) {
$_pairs[] = "'$key'=>$value";
$_vars_nc .= "\$_smarty_tpl->tpl_vars['$key'] = new Smarty_Variable($value);\n";
}
$_vars = 'array(' . join(',', $_pairs) . ')';
$_has_vars = true;
} 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()';
$_has_vars = false;
}
if ($has_compiled_template) {
$_hash = $compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash'];
$_output = "<?php /* Call merged included template \"" . $tpl_name . "\" */\n";
$_output .= "\$_tpl_stack[] = \$_smarty_tpl;\n";
$_output .= " \$_smarty_tpl = \$_smarty_tpl->setupInlineSubTemplate($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, '$_hash');\n";
$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;
}
if (isset($_assign)) {
$_output .= 'ob_start(); ';
$_output .= "ob_start();\n";
}
$_output .= $compiler->smarty->merged_templates_func[$tpl_name]['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 .= "/* 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;
}
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Include PHP
*
* Compiles the {include_php} tag
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -24,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.
*
@ -31,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.
*
@ -43,10 +44,13 @@ 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
* @return string compiled code
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
*
* @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");
@ -54,13 +58,15 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase {
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$_output = '<?php ';
/** @var Smarty_Internal_Template $_smarty_tpl
* used in evaluated code
*/
$_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;
@ -69,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)) {
@ -97,12 +103,9 @@ 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";
}
}
}
?>

View file

@ -2,7 +2,6 @@
/**
* Smarty Internal Plugin Compile Insert
*
* Compiles the {insert} tag
*
* @package Smarty
@ -16,8 +15,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -25,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.
*
@ -32,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.
*
@ -44,35 +45,45 @@ 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 \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
$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;
$_script = null;
$_output = '<?php ';
// save posible attributes
eval('$_name = ' . $_attr['name'] . ';');
// save possible attributes
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 shure that the compiler knows about its nocache status
$compiler->template->tpl_vars[trim($_attr['assign'], "'")] = new Smarty_Variable(null, true);
// create variable to make sure that the compiler knows about its nocache status
$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,22 +132,20 @@ 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);?>";
}
}
return $_output;
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Ldelim
*
* Compiles the {ldelim} tag
*
* @package Smarty
@ -15,27 +14,27 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Ldelim extends Smarty_Internal_CompileBase {
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 \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;
return $compiler->smarty->left_delimiter;
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Nocache
*
* Compiles the {nocache} {/nocache} tags.
*
* @package Smarty
@ -10,35 +9,40 @@
*/
/**
* Smarty Internal Plugin Compile Nocache Classv
* Smarty Internal Plugin Compile Nocache Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Nocache extends Smarty_Internal_CompileBase {
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 \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
$compiler->has_code = false;
return true;
}
}
/**
@ -47,27 +51,25 @@ class Smarty_Internal_Compile_Nocache extends Smarty_Internal_CompileBase {
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Nocacheclose extends Smarty_Internal_CompileBase {
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 \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;
return true;
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Block Plugin
*
* Compiles code for the execution of block plugin
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -29,13 +28,14 @@ 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 \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,13 +75,15 @@ 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";
}
}
?>

View file

@ -0,0 +1,224 @@
<?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)
{
// 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);
}
$className = 'Smarty_Internal_Compile_' . ucfirst($tag);
if ((!isset($parameter[2]) || false === $property = $compiler->getId($parameter[2])) ||
!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)";
}
}

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Function Plugin
*
* Compiles code for the execution of function plugin
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_Function_Plugin extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Private_Function_Plugin extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -24,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.
*
@ -36,13 +36,14 @@ 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 \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
*
* @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;
@ -65,9 +66,7 @@ class Smarty_Internal_Compile_Private_Function_Plugin extends Smarty_Internal_Co
$_params = 'array(' . implode(",", $_paramsArray) . ')';
// compile code
$output = "<?php echo {$function}({$_params},\$_smarty_tpl);?>\n";
return $output;
}
}
?>

View file

@ -2,7 +2,6 @@
/**
* Smarty Internal Plugin Compile Modifier
*
* Compiles code for modifier execution
*
* @package Smarty
@ -16,17 +15,20 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBase
{
/**
* Compiles code for modifier execution
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @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);
$output = $parameter['value'];
@ -51,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 . ')';
}
@ -72,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);
}
@ -84,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;
@ -95,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;
@ -104,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 {
@ -129,12 +146,10 @@ 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);
}
}
return $output;
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Object Block Function
*
* Compiles code for registered objects as block function
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -29,13 +28,14 @@ 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 \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,13 +77,15 @@ 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";
}
}
?>

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Object Funtion
*
* Smarty Internal Plugin Compile Object Function
* Compiles code for registered objects as function
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_Object_Function extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Private_Object_Function extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -29,13 +28,14 @@ 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 \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);
@ -48,6 +48,8 @@ class Smarty_Internal_Compile_Private_Object_Function extends Smarty_Internal_Co
$_assign = $_attr['assign'];
unset($_attr['assign']);
}
// method or property ?
if (method_exists($compiler->smarty->registered_objects[$tag][0], $method)) {
// convert attributes into parameter array string
if ($compiler->smarty->registered_objects[$tag][2]) {
$_paramsArray = array();
@ -64,6 +66,11 @@ class Smarty_Internal_Compile_Private_Object_Function extends Smarty_Internal_Co
$_params = implode(",", $_attr);
$return = "\$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params})";
}
} else {
// object property
$return = "\$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}";
}
if (empty($_assign)) {
// This tag does create output
$compiler->has_output = true;
@ -71,9 +78,7 @@ class Smarty_Internal_Compile_Private_Object_Function extends Smarty_Internal_Co
} else {
$output = "<?php \$_smarty_tpl->assign({$_assign},{$return});?>\n";
}
return $output;
}
}
?>

View file

@ -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);
}
}

View file

@ -1,7 +1,6 @@
<?php
/**
* Smarty Internal Plugin Compile Print Expression
*
* Compiles any tag which will output an expression or variable
*
* @package Smarty
@ -15,8 +14,8 @@
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_CompileBase {
class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
@ -24,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.
*
@ -33,14 +33,16 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
public $option_flags = array('nocache', 'nofilter');
/**
* Compiles code for gererting output from any expression
* Compiles code for generating output from any expression
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param array $parameter array with compilation parameter
* @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);
@ -48,12 +50,6 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
if ($_attr['nocache'] === true) {
$compiler->tag_nocache = true;
}
// filter handling
if ($_attr['nofilter'] === true) {
$_filter = 'false';
} else {
$_filter = 'true';
}
if (isset($_attr['assign'])) {
// assign output to variable
$output = "<?php \$_smarty_tpl->assign({$_attr['assign']},{$parameter['value']});?>";
@ -62,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
@ -79,19 +76,21 @@ 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) {
$output = "htmlspecialchars({$output}, ENT_QUOTES, '" . addslashes(Smarty::$_CHARSET) . "')";
}
// loop over registerd filters
// 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])) {
$output = "\$_smarty_tpl->smarty->registered_filters[Smarty::FILTER_VARIABLE][{$key}][0]->{$function[1]}({$output},\$_smarty_tpl)";
$output = "\$_smarty_tpl->smarty->registered_filters[Smarty::FILTER_VARIABLE]['{$key}'][0]->{$function[1]}({$output},\$_smarty_tpl)";
} else {
$output = "{$function[0]}::{$function[1]}({$output},\$_smarty_tpl)";
}
@ -109,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) {
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));
}
$output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => array($filter),
'value' => $output));
}
}
}
@ -123,34 +123,34 @@ class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_C
$compiler->has_output = true;
$output = "<?php echo {$output};?>";
}
return $output;
}
/**
* @param object $compiler compiler object
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
* @param string $name name of variable filter
* @param type $output embedded output
* @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
return false;
}
return "{$plugin_name}({$output},\$_smarty_tpl)";
}
}
?>

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