Compare commits

..

8 Commits

709 changed files with 32864 additions and 24577 deletions
+9 -11
View File
@@ -25,6 +25,7 @@ jobs:
- ubuntu-latest
php-version:
- "7.1"
- "7.2"
- "7.3"
- "7.4"
@@ -48,7 +49,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v2
- name: Override PHP ini values for JIT compiler
if: matrix.compiler == 'jit'
@@ -62,20 +63,17 @@ jobs:
extensions: ${{ env.PHP_EXTENSIONS }}
ini-values: ${{ env.PHP_INI_VALUES }}
- name: Validate composer.json and composer.lock
run: composer validate
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
uses: actions/cache@v2
with:
path: vendor
key: v5r2-${{ runner.os }}-php-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}
key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}
restore-keys: |
v5r1-${{ runner.os }}-php-${{ matrix.php-version }}-
- name: Install dependencies
uses: php-actions/composer@v6
- name: Run make
run: make -B
${{ runner.os }}-php-${{ matrix.php-version }}-
- name: Run tests with phpunit
run: php ./vendor/phpunit/phpunit/phpunit
run: ./run-tests.sh
+8 -2
View File
@@ -1,7 +1,13 @@
.idea/
# Smarty
lexer/*.php
lexer/*.php.bak
lexer/*.out
# Dev
phpunit*
.phpunit.result.cache
/vendor/*
/composer.lock
vendor/*
composer.lock
+4 -62
View File
@@ -6,72 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Added support for PHP8.2
### Changed
- All Smarty code is now in the \Smarty namespace. For simple use-cases, you only need to add
`use \Smarty\Smarty;` to your script and everything will work. If you extend Smarty or use
Smarty plug-ins, please review your code to see if they assume specific class or method names.
E.g.: `Smarty_Internal_Template` is now `\Smarty\Template\`, `SmartyException` is now `\Smarty\Exception`.
- Template variable scope bubbling has been simplified and made more consistent.
The global scope now equals the Smarty scope in order to avoid global state side effects. Please read
the documentation for more details.
- Lexers and Parsers PHP files are no longer under version control, but generated from sources (.y and .plex)
- Smarty now always runs in multibyte mode, using `symfony/polyfill-mbstring` if required. Please use the
multibyte extension for optimal performance.
### Deprecated
- `$smarty->getPluginsDir()`
- `$smarty->loadFilter()`
- `$smarty->setPluginsDir()`
- `$smarty->assignGlobal()`
- Using `$smarty->registerFilter()` for registering variable filters will trigger a notice.
-
### Removed
- Dropped support for PHP7.1
- Removed `$smarty->left_delimiter` and `$smarty->right_delimiter`, use `$smarty->getLeftDelimiter()`/`$smarty->setLeftDelimiter()` and `$smarty->getRightDelimiter()`/`$smarty->setRightDelimiter()`
- Removed support for the `$cache_attrs` parameter for registered plugins
- Removed support for undocumented `{make_nocache}` tag
- Removed support for deprecated `{insert}` tag, the 'insert' plugin type and the associated $smarty->trusted_dir variable
- Removed the undocumented `{block_parent}` and `{parent}` alternatives to `{$smarty.block.parent}`
- Removed the undocumented `{block_child}` and `{child}` alternatives to `{$smarty.block.child}`
- Removed support for loading config files into a non-local scope using `{config_load}` from a template
- Removed `$smarty->autoload_filters` in favor of `$smarty->registerFilter()`
- Removed `$smarty->trusted_dir` and `$smarty->allow_php_templates` since support for executing php scripts from templates has been dropped
- Removed `$smarty->php_functions` and `$smarty->php_modifiers`. If you need a PHP-function in your templates,
register it as a modifier.
- Removed support for `$smarty->getTags()`
- Removed the abandoned `$smarty->direct_access_security` setting
- Dropped support for `$smarty->plugins_dir` and `$smarty->use_include_path`. If you must, use `$smarty->addPluginsDir()` instead,
but it's better to use Smarty::addExtension() to add an extension or Smarty::registerPlugin to
quickly register a plugin using a callback function.
- Removed constants such as SMARTY_DIR to prevent global side effects.
- Removed direct access to `$smarty->template_dir`. Use `$smarty->setTemplateDir()`.
- Removed direct access to `$smarty->cache_dir`. Use `$smarty->setCacheDir()`.
- Removed `$smarty->loadPlugin()`, use `$smarty->registerPlugin()` instead.
- Removed `$smarty->appendByRef()` and `$smarty->assignByRef()`.
- Removed `$smarty->use_sub_dirs`. Cached files are now automatically stored in subdirs for maximum performance.
### Fixed
- `$smarty->muteUndefinedOrNullWarnings()` now also mutes PHP7 notices for undefined array indexes [#736](https://github.com/smarty-php/smarty/issues/736)
- `$smarty->muteUndefinedOrNullWarnings()` now treats undefined vars and array access of a null or false variables
equivalent across all supported PHP versions
- `$smarty->muteUndefinedOrNullWarnings()` now allows dereferencing of non-objects across all supported PHP versions [#831](https://github.com/smarty-php/smarty/issues/831)
- PHP 8.1 deprecation warnings on null strings in modifiers [#834](https://github.com/smarty-php/smarty/pull/834)
## [4.3.0] - 2022-11-22
### Added
- PHP8.2 compatibility [#775](https://github.com/smarty-php/smarty/pull/775)
### Changed
- Include docs and demo in the releases [#799](https://github.com/smarty-php/smarty/issues/799)
- Using PHP functions as modifiers now triggers a deprecation notice because we will drop support for this in the next major release [#813](https://github.com/smarty-php/smarty/issues/813)
- Dropped remaining references to removed PHP-support in Smarty 4 from docs, lexer and security class. [#816](https://github.com/smarty-php/smarty/issues/816)
- Support umask when writing (template) files and set dir permissions to 777 [#548](https://github.com/smarty-php/smarty/issues/548) [#819](https://github.com/smarty-php/smarty/issues/819)
- Dropped remaining references to removed PHP-support in Smarty 4 from docs, lexer and security class. [#816](https://github.com/smarty-php/smarty/issues/816)
### Fixed
- Output buffer is now cleaned for internal PHP errors as well, not just for Exceptions [#514](https://github.com/smarty-php/smarty/issues/514)
- Fixed recursion and out of memory errors when caching in complicated template set-ups using inheritance and includes [#801](https://github.com/smarty-php/smarty/pull/801)
@@ -1825,7 +1767,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
27.09.2011
- bugfix possible warning "attempt to modify property of non-object" in {section} (issue #34)
- added chaining to \Smarty\Data so $smarty->assign('a',1)->assign('b',2); is possible now
- added chaining to Smarty_Internal_Data so $smarty->assign('a',1)->assign('b',2); is possible now
- bugfix remove race condition when a custom resource did change timestamp during compilation
- bugfix variable property did not work on objects variable in template
- bugfix smarty_make_timestamp() failed to process DateTime objects properly
@@ -2160,7 +2102,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- optimize smarty_modified_escape for hex, hexentity, decentity.
28/12/2010
- changed $tpl_vars, $config_vars and $parent to belong to \Smarty\Data
- changed $tpl_vars, $config_vars and $parent to belong to Smarty_Internal_Data
- added Smarty::registerCacheResource() for dynamic cache resource object registration
27/12/2010
-19
View File
@@ -1,19 +0,0 @@
all: lexers parsers
lexers: src/Lexer/ConfigfileLexer.php src/Lexer/TemplateLexer.php
parsers: src/Parser/ConfigfileParser.php src/Parser/TemplateParser.php
src/Lexer/ConfigfileLexer.php: src/Lexer/ConfigfileLexer.plex
php ./utilities/make-lexer.php src/Lexer/ConfigfileLexer.plex src/Lexer/ConfigfileLexer.php
src/Lexer/TemplateLexer.php: src/Lexer/TemplateLexer.plex
php ./utilities/make-lexer.php src/Lexer/TemplateLexer.plex src/Lexer/TemplateLexer.php
src/Parser/ConfigfileParser.php: src/Parser/ConfigfileParser.y
php ./utilities/make-parser.php src/Parser/ConfigfileParser.y src/Parser/ConfigfileParser.php
src/Parser/TemplateParser.php: src/Parser/TemplateParser.y
php ./utilities/make-parser.php src/Parser/TemplateParser.y src/Parser/TemplateParser.php
clean:
rm -f src/Lexer/ConfigfileLexer.php src/Lexer/TemplateLexer.php src/Parser/ConfigfileParser.php src/Parser/TemplateParser.php
+1 -1
View File
@@ -7,7 +7,7 @@ Smarty is a template engine for PHP, facilitating the separation of presentation
Read the [documentation](https://smarty-php.github.io/smarty/) to find out how to use it.
## Requirements
Smarty v5 can be run with PHP 7.2 to PHP 8.2.
Smarty can be run with PHP 7.1 to PHP 8.2.
## Installation
Smarty versions 3.1.11 or later can be installed with [Composer](https://getcomposer.org/).
-48
View File
@@ -1,48 +0,0 @@
# @TODO
## Review direct variable property access
- review ->value{$index} in ForTag
- review ->(step|total|first|last|do_else|key|show|iteration|index)
- review ->tpl_vars, ->config_vars, ->value
- Re-introduce merge_compiled_includes and the {include inline} attribute?
## Beatify output
- strip <?php and ?> tags from generated output
## Review public static vars
- such as _CHARSET and _IS_WINDOWS
## Build
- add compiled lexers and parsers to Release assets automatically
## Benchmark
- benchmark to see that performance hasn't degraded
## Block / inheritance
- Consider phasing out $smarty.block.child as this reverses the inheritance hierarchy and might cause infinite loops
when combined with $smarty.block.parent
## Plugin system
- fix template security checks in one place in compiler
## Documentation
- beautify and review docs, possibly using [
Material for MkDocs ](https://squidfunk.github.io/mkdocs-material/publishing-your-site/)
## Resources
- Fix circular deps between resources and sources
```
$smarty = $this->_getSmartyObj();
[$name, $type] = \Smarty\Resource\BasePlugin::parseResourceName($config_file, $smarty->default_config_type);
$source = new Config($smarty, $config_file, $type, $name);
$source->handler->getContent($source);
```
## Unrelated / other
- review (and avoid) use of 'clone' keyword
- compiler->has_code seems silly. Why not have proper return values?
- what is 'user literal support', why are unit tests skipped?
+5 -10
View File
@@ -30,25 +30,20 @@
"forum": "https://github.com/smarty-php/smarty/discussions"
},
"require": {
"php": "^7.2 || ^8.0",
"symfony/polyfill-mbstring": "^1.27",
"nette/php-generator": "^3.6"
"php": "^7.1 || ^8.0"
},
"autoload": {
"psr-4" : {
"Smarty\\" : "src/"
},
"files": [
"src/functions.php"
"classmap": [
"libs/"
]
},
"extra": {
"branch-alias": {
"dev-master": "5.0.x-dev"
"dev-master": "4.0.x-dev"
}
},
"require-dev": {
"phpunit/phpunit": "^8.5 || ^7.5",
"smarty/smarty-lexer": "dev-master"
"smarty/smarty-lexer": "^3.1"
}
}
+4 -4
View File
@@ -2,11 +2,11 @@
/**
* Example Application
*
* @package Example-application
*/
$smarty = new \Smarty\Smarty;
require '../libs/Smarty.class.php';
$smarty = new Smarty;
//$smarty->force_compile = true;
$smarty->debugging = true;
$smarty->caching = true;
$smarty->cache_lifetime = 120;
@@ -6,11 +6,23 @@
* memcache as the storage resource for Smarty's output caching.
* *
*
* @package CacheResource-examples
* @author Uwe Tews
*/
class Smarty_CacheResource_Apc extends \Smarty\Cacheresource\KeyValueStore
class Smarty_CacheResource_Apc extends Smarty_CacheResource_KeyValueStore
{
/**
* Smarty_CacheResource_Apc constructor.
*
* @throws \Exception
*/
public function __construct()
{
// test if APC is present
if (!function_exists('apc_cache_info')) {
throw new Exception('APC Template Caching Error: APC is not installed');
}
}
/**
* Read values for a set of keys from cache
@@ -7,32 +7,30 @@
* Note that memcache has a limitation of 256 characters per cache-key.
* To avoid complications all cache-keys are translated to a sha1 hash.
*
* @package CacheResource-examples
* @author Rodney Rehm
*/
class Smarty_CacheResource_Memcache extends \Smarty\Cacheresource\KeyValueStore
class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore
{
/**
* memcache instance
*
* @var Memcache
*/
private $memcache = null;
protected $memcache = null;
/**
* @return Memcache|Memcached
*/
public function getMemcache() {
if ($this->memcache === null) {
if (class_exists('Memcached')) {
$this->memcache = new Memcached();
} else {
$this->memcache = new Memcache();
}
$this->memcache->addServer('127.0.0.1', 11211);
}
return $this->memcache;
}
/**
* Smarty_CacheResource_Memcache constructor.
*/
public function __construct()
{
if (class_exists('Memcached')) {
$this->memcache = new Memcached();
} else {
$this->memcache = new Memcache();
}
$this->memcache->addServer('127.0.0.1', 11211);
}
/**
* Read values for a set of keys from cache
@@ -47,7 +45,7 @@ class Smarty_CacheResource_Memcache extends \Smarty\Cacheresource\KeyValueStore
$res = array();
foreach ($keys as $key) {
$k = sha1($key);
$res[$key] = $this->getMemcache()->get($k);
$res[$key] = $this->memcache->get($k);
}
return $res;
}
@@ -65,9 +63,9 @@ class Smarty_CacheResource_Memcache extends \Smarty\Cacheresource\KeyValueStore
foreach ($keys as $k => $v) {
$k = sha1($k);
if (class_exists('Memcached')) {
$this->getMemcache()->set($k, $v, $expire);
$this->memcache->set($k, $v, $expire);
} else {
$this->getMemcache()->set($k, $v, 0, $expire);
$this->memcache->set($k, $v, 0, $expire);
}
}
return true;
@@ -84,7 +82,7 @@ class Smarty_CacheResource_Memcache extends \Smarty\Cacheresource\KeyValueStore
{
foreach ($keys as $k) {
$k = sha1($k);
$this->getMemcache()->delete($k);
$this->memcache->delete($k);
}
return true;
}
@@ -96,6 +94,6 @@ class Smarty_CacheResource_Memcache extends \Smarty\Cacheresource\KeyValueStore
*/
protected function purge()
{
return $this->getMemcache()->flush();
return $this->memcache->flush();
}
}
@@ -1,7 +1,5 @@
<?php
use Smarty\Exception;
/**
* MySQL CacheResource
* CacheResource Implementation based on the Custom API to use
@@ -21,73 +19,68 @@ use Smarty\Exception;
* INDEX(`modified`)
* ) ENGINE = InnoDB;</pre>
*
* @package CacheResource-examples
* @author Rodney Rehm
*/
class Smarty_CacheResource_Mysql extends \Smarty\Cacheresource\Custom
class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom
{
/**
* @var \PDO
*/
protected $db;
/**
* @return PDO
* @throws Exception
*/
protected function db(): PDO {
static $dbConn = null;
try {
return $dbConn ?? ($dbConn = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty"));
} catch (PDOException $e) {
throw new Exception('Mysql Resource failed: ' . $e->getMessage());
}
}
/**
* @var \PDOStatement
*/
protected $fetch;
/**
* @return false|PDOStatement
* @throws Exception
*/
protected function fetchQuery() {
static $query = null;
return $query ?? $query = $this->db()->prepare('SELECT modified, content FROM output_cache WHERE id = :id');
}
/**
* @var \PDOStatement
*/
protected $fetchTimestamp;
/**
* @return false|PDOStatement
* @throws Exception
*/
protected function fetchTimestampQuery() {
static $query = null;
return $query ?? $query = $this->db()->prepare('SELECT modified FROM output_cache WHERE id = :id');
}
/**
* @var \PDOStatement
*/
protected $save;
/**
* @return false|PDOStatement
* @throws Exception
*/
protected function saveQuery() {
static $query = null;
return $query ?? $query = $this->db()->prepare(
'REPLACE INTO output_cache (id, name, cache_id, compile_id, content)
/**
* Smarty_CacheResource_Mysql constructor.
*
* @throws \SmartyException
*/
public function __construct()
{
try {
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
} catch (PDOException $e) {
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, content FROM output_cache WHERE id = :id');
$this->fetchTimestamp = $this->db->prepare('SELECT modified FROM output_cache WHERE id = :id');
$this->save = $this->db->prepare(
'REPLACE INTO output_cache (id, name, cache_id, compile_id, content)
VALUES (:id, :name, :cache_id, :compile_id, :content)'
);
}
);
}
/**
* fetch cached content and its modification time from data source
*
* @param string $id unique cache content identifier
* @param string $name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param string $content cached content
* @param integer $mtime cache modification timestamp (epoch)
*
* @return void
* @throws Exception
*/
/**
* fetch cached content and its modification time from data source
*
* @param string $id unique cache content identifier
* @param string $name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param string $content cached content
* @param integer $mtime cache modification timestamp (epoch)
*
* @return void
*/
protected function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime)
{
$this->fetchQuery()->execute(array('id' => $id));
$row = $this->fetchQuery()->fetch();
$this->fetchQuery()->closeCursor();
$this->fetch->execute(array('id' => $id));
$row = $this->fetch->fetch();
$this->fetch->closeCursor();
if ($row) {
$content = $row[ 'content' ];
$mtime = strtotime($row[ 'modified' ]);
@@ -112,9 +105,9 @@ class Smarty_CacheResource_Mysql extends \Smarty\Cacheresource\Custom
*/
protected function fetchTimestamp($id, $name, $cache_id, $compile_id)
{
$this->fetchTimestampQuery()->execute(array('id' => $id));
$mtime = strtotime($this->fetchTimestampQuery()->fetchColumn());
$this->fetchTimestampQuery()->closeCursor();
$this->fetchTimestamp->execute(array('id' => $id));
$mtime = strtotime($this->fetchTimestamp->fetchColumn());
$this->fetchTimestamp->closeCursor();
return $mtime;
}
@@ -132,14 +125,14 @@ class Smarty_CacheResource_Mysql extends \Smarty\Cacheresource\Custom
*/
protected function save($id, $name, $cache_id, $compile_id, $exp_time, $content)
{
$this->saveQuery()->execute(
$this->save->execute(
array('id' => $id,
'name' => $name,
'cache_id' => $cache_id,
'compile_id' => $compile_id,
'content' => $content,)
);
return !!$this->saveQuery()->rowCount();
return !!$this->save->rowCount();
}
/**
@@ -157,18 +150,18 @@ class Smarty_CacheResource_Mysql extends \Smarty\Cacheresource\Custom
// delete the whole cache
if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
// returning the number of deleted caches would require a second query to count them
$query = $this->db()->query('TRUNCATE TABLE output_cache');
$query = $this->db->query('TRUNCATE TABLE output_cache');
return -1;
}
// build the filter
$where = array();
// equal test name
if ($name !== null) {
$where[] = 'name = ' . $this->db()->quote($name);
$where[] = 'name = ' . $this->db->quote($name);
}
// equal test compile_id
if ($compile_id !== null) {
$where[] = 'compile_id = ' . $this->db()->quote($compile_id);
$where[] = 'compile_id = ' . $this->db->quote($compile_id);
}
// range test expiration time
if ($exp_time !== null) {
@@ -178,13 +171,13 @@ class Smarty_CacheResource_Mysql extends \Smarty\Cacheresource\Custom
if ($cache_id !== null) {
$where[] =
'(cache_id = ' .
$this->db()->quote($cache_id) .
$this->db->quote($cache_id) .
' OR cache_id LIKE ' .
$this->db()->quote($cache_id . '|%') .
$this->db->quote($cache_id . '|%') .
')';
}
// run delete query
$query = $this->db()->query('DELETE FROM output_cache WHERE ' . join(' AND ', $where));
$query = $this->db->query('DELETE FROM output_cache WHERE ' . join(' AND ', $where));
return $query->rowCount();
}
}
@@ -1,7 +1,5 @@
<?php
use Smarty\Exception;
/**
* PDO Cache Handler
* Allows you to store Smarty Cache files into your db.
@@ -24,11 +22,12 @@ use Smarty\Exception;
* Example usage :
* $cnx = new PDO("mysql:host=localhost;dbname=mydb", "username", "password");
* $smarty->setCachingType('pdo');
* $smarty->loadPlugin('Smarty_CacheResource_Pdo');
* $smarty->registerCacheResource('pdo', new Smarty_CacheResource_Pdo($cnx, 'smarty_cache'));
*
* @author Beno!t POLASZEK - 2014
*/
class Smarty_CacheResource_Pdo extends \Smarty\Cacheresource\Custom
class Smarty_CacheResource_Pdo extends Smarty_CacheResource_Custom
{
/**
* @var string[]
@@ -121,12 +120,12 @@ class Smarty_CacheResource_Pdo extends \Smarty\Cacheresource\Custom
* @param string $table : table (or view) name
* @param string $database : optional - if table is located in another db
*
* @throws \Smarty\Exception
* @throws \SmartyException
*/
public function __construct(PDO $pdo, $table, $database = null)
{
if (is_null($table)) {
throw new Exception("Table name for caching can't be null");
throw new SmartyException("Table name for caching can't be null");
}
$this->pdo = $pdo;
$this->table = $table;
@@ -323,7 +322,7 @@ class Smarty_CacheResource_Pdo extends \Smarty\Cacheresource\Custom
$where[] = 'compile_id = ' . $this->pdo->quote($compile_id);
}
// for clearing expired caches
if ($exp_time === \Smarty\Smarty::CLEAR_EXPIRED) {
if ($exp_time === Smarty::CLEAR_EXPIRED) {
$where[] = 'expire < CURRENT_TIMESTAMP';
} // range test expiration time
elseif ($exp_time !== null) {
@@ -1,12 +1,12 @@
<?php
require_once __DIR__ . '/cacheresource.pdo.php';
require_once 'cacheresource.pdo.php';
/**
* PDO Cache Handler with GZIP support
* Example usage :
* $cnx = new PDO("mysql:host=localhost;dbname=mydb", "username", "password");
* $smarty->setCachingType('pdo_gzip');
* $smarty->loadPlugin('Smarty_CacheResource_Pdo_Gzip');
* $smarty->registerCacheResource('pdo_gzip', new Smarty_CacheResource_Pdo_Gzip($cnx, 'smarty_cache'));
*
* @require Smarty_CacheResource_Pdo class
@@ -1,43 +1,38 @@
<?php
use Smarty\Exception;
use Smarty\Template;
use Smarty\Template\Source;
/**
* Extends All Resource
* Resource Implementation modifying the extends-Resource to walk
* through the template_dirs and inherit all templates of the same name
*
* @package Resource-examples
* @author Rodney Rehm
*/
class My_Resource_Extendsall extends \Smarty\Resource\ExtendsPlugin
class Smarty_Resource_Extendsall extends Smarty_Internal_Resource_Extends
{
/**
* populate Source Object with meta data from Resource
*
* @param Source $source source object
* @param Template $_template template object
* @param Smarty_Template_Source $source source object
* @param Smarty_Internal_Template $_template template object
*
* @return void
*/
public function populate(Source $source, Template $_template = null)
public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
{
$uid = '';
$sources = array();
$timestamp = 0;
foreach ($source->getSmarty()->getTemplateDir() as $key => $directory) {
foreach ($source->smarty->getTemplateDir() as $key => $directory) {
try {
$s = \Smarty\Template\Source::load(null, $source->getSmarty(),
'file:' . '[' . $key . ']' . $source->name);
$s = Smarty_Resource::source(null, $source->smarty, 'file:' . '[' . $key . ']' . $source->name);
if (!$s->exists) {
continue;
}
$sources[ $s->uid ] = $s;
$uid .= $s->filepath;
$timestamp = $s->timestamp > $timestamp ? $s->timestamp : $timestamp;
} catch (Exception $e) {
} catch (SmartyException $e) {
}
}
if (!$sources) {
@@ -49,7 +44,7 @@ class My_Resource_Extendsall extends \Smarty\Resource\ExtendsPlugin
$s = current($sources);
$source->components = $sources;
$source->filepath = $s->filepath;
$source->uid = sha1($uid . $source->getSmarty()->_joined_template_dir);
$source->uid = sha1($uid . $source->smarty->_joined_template_dir);
$source->exists = true;
$source->timestamp = $timestamp;
}
+101
View File
@@ -0,0 +1,101 @@
<?php
/**
* MySQL Resource
* Resource Implementation based on the Custom API to use
* MySQL as the storage resource for Smarty's templates and configs.
* Table definition:
* <pre>CREATE TABLE IF NOT EXISTS `templates` (
* `name` varchar(100) NOT NULL,
* `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
* `source` text,
* PRIMARY KEY (`name`)
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pre>
* Demo data:
* <pre>INSERT INTO `templates` (`name`, `modified`, `source`) VALUES ('test.tpl', "2010-12-25 22:00:00", '{$x="hello
* world"}{$x}');</pre>
*
*
* @package Resource-examples
* @author Rodney Rehm
*/
class Smarty_Resource_Mysql extends Smarty_Resource_Custom
{
/**
* PDO instance
*
* @var \PDO
*/
protected $db;
/**
* prepared fetch() statement
*
* @var \PDOStatement
*/
protected $fetch;
/**
* prepared fetchTimestamp() statement
*
* @var \PDOStatement
*/
protected $mtime;
/**
* Smarty_Resource_Mysql constructor.
*
* @throws \SmartyException
*/
public function __construct()
{
try {
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
} catch (PDOException $e) {
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
$this->mtime = $this->db->prepare('SELECT modified FROM templates WHERE name = :name');
}
/**
* Fetch a template and its modification time from database
*
* @param string $name template name
* @param string $source template source
* @param integer $mtime template modification timestamp (epoch)
*
* @return void
*/
protected function fetch($name, &$source, &$mtime)
{
$this->fetch->execute(array('name' => $name));
$row = $this->fetch->fetch();
$this->fetch->closeCursor();
if ($row) {
$source = $row[ 'source' ];
$mtime = strtotime($row[ 'modified' ]);
} else {
$source = null;
$mtime = null;
}
}
/**
* Fetch a template's modification time from database
*
* @note implementing this method is optional. Only implement it if modification times can be accessed faster than
* loading the comple template source.
*
* @param string $name template name
*
* @return integer timestamp (epoch) the template was modified
*/
protected function fetchTimestamp($name)
{
$this->mtime->execute(array('name' => $name));
$mtime = $this->mtime->fetchColumn();
$this->mtime->closeCursor();
return strtotime($mtime);
}
}
+77
View File
@@ -0,0 +1,77 @@
<?php
/**
* MySQL Resource
* Resource Implementation based on the Custom API to use
* MySQL as the storage resource for Smarty's templates and configs.
* Note that this MySQL implementation fetches the source and timestamps in
* a single database query, instead of two separate like resource.mysql.php does.
* Table definition:
* <pre>CREATE TABLE IF NOT EXISTS `templates` (
* `name` varchar(100) NOT NULL,
* `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
* `source` text,
* PRIMARY KEY (`name`)
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pre>
* Demo data:
* <pre>INSERT INTO `templates` (`name`, `modified`, `source`) VALUES ('test.tpl', "2010-12-25 22:00:00", '{$x="hello
* world"}{$x}');</pre>
*
*
* @package Resource-examples
* @author Rodney Rehm
*/
class Smarty_Resource_Mysqls extends Smarty_Resource_Custom
{
/**
* PDO instance
*
* @var \PDO
*/
protected $db;
/**
* prepared fetch() statement
*
* @var \PDOStatement
*/
protected $fetch;
/**
* Smarty_Resource_Mysqls constructor.
*
* @throws \SmartyException
*/
public function __construct()
{
try {
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
} catch (PDOException $e) {
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
}
/**
* Fetch a template and its modification time from database
*
* @param string $name template name
* @param string $source template source
* @param integer $mtime template modification timestamp (epoch)
*
* @return void
*/
protected function fetch($name, &$source, &$mtime)
{
$this->fetch->execute(array('name' => $name));
$row = $this->fetch->fetch();
$this->fetch->closeCursor();
if ($row) {
$source = $row[ 'source' ];
$mtime = strtotime($row[ 'modified' ]);
} else {
$source = null;
$mtime = null;
}
}
}
+2
View File
@@ -11,6 +11,8 @@
The current date and time is {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
The value of global assigned variable $SCRIPT_NAME is {$SCRIPT_NAME}
Example of accessing server environment variable SERVER_NAME: {$smarty.server.SERVER_NAME}
The value of {ldelim}$Name{rdelim} is <b>{$Name}</b>
+7 -1
View File
@@ -3,10 +3,16 @@ services:
base:
build:
context: .
dockerfile: ./utilities/testrunners/php72/Dockerfile
dockerfile: ./utilities/testrunners/php71/Dockerfile
volumes:
- .:/app
working_dir: /app
entrypoint: sh ./run-tests.sh
php71:
extends:
service: base
build:
dockerfile: ./utilities/testrunners/php71/Dockerfile
php72:
extends:
service: base
+2 -1
View File
@@ -11,7 +11,8 @@ of the console.
Set [`$debugging`](../programmers/api-variables/variable-debugging.md) to TRUE in Smarty, and if needed
set [`$debug_tpl`](../programmers/api-variables/variable-debug-template.md) to the template resource
path to `debug.tpl`. When you load the page, a Javascript console window will pop
path to `debug.tpl` (this is in [`SMARTY_DIR`](../programmers/smarty-constants.md) by
default). When you load the page, a Javascript console window will pop
up and give you the names of all the included templates and assigned
variables for the current page.
@@ -10,6 +10,7 @@ within delimiters like so: `{funcname attr1="val1" attr2="val2"}`.
{config_load file="colors.conf"}
{include file="header.tpl"}
{insert file="banner_ads.tpl" title="My Site"}
{if $logged_in}
Welcome, <span style="color:{#fontColor#}">{$name}!</span>
@@ -16,6 +16,7 @@ Built-in Functions {#language.builtin.functions}
- [{function}](./language-builtin-functions/language-function-function.md)
- [{if},{elseif},{else}](./language-builtin-functions/language-function-if.md)
- [{include}](./language-builtin-functions/language-function-include.md)
- [{insert}](./language-builtin-functions/language-function-insert.md)
- [{ldelim},{rdelim}](./language-builtin-functions/language-function-ldelim.md)
- [{literal}](./language-builtin-functions/language-function-literal.md)
- [{nocache}](./language-builtin-functions/language-function-nocache.md)
@@ -17,7 +17,7 @@
var string Yes *n/a* The name of the variable being assigned
value string Yes *n/a* The value being assigned
index string No *n/a* The index for the new array element. If not specified the value is append to the end of the array.
scope string No *n/a* The scope of the assigned variable: \'parent\',\'root\' or \'smarty\'
scope string No *n/a* The scope of the assigned variable: \'parent\',\'root\' or \'global\'
**Option Flags:**
@@ -21,7 +21,7 @@ execution of a template**.
---------------- -------- ---------- --------- -----------------------------------------------------------------------
var string Yes *n/a* The name of the variable being assigned
value string Yes *n/a* The value being assigned
scope string No *n/a* The scope of the assigned variable: \'parent\',\'root\' or \'smarty\'
scope string No *n/a* The scope of the assigned variable: \'parent\',\'root\' or \'global\'
**Option Flags:**
@@ -135,6 +135,7 @@ The following functions can also *optionally* assign template variables.
[`{capture}`](#language.function.capture),
[`{include}`](#language.function.include),
[`{insert}`](#language.function.insert),
[`{counter}`](#language.function.counter),
[`{cycle}`](#language.function.cycle),
[`{eval}`](#language.function.eval),
@@ -28,6 +28,13 @@ is the value passed in the `name` attribute. If you do not supply the
--------- -----------------------------------------
nocache Disables caching of this captured block
> **Note**
>
> Be careful when capturing [`{insert}`](#language.function.insert)
> output. If you have [`$caching`](#caching) enabled and you have
> [`{insert}`](#language.function.insert) commands that you expect to
> run within cached content, do not capture this content.
{* we don't want to print a div tag unless content is displayed *}
{capture name="banner"}
@@ -8,6 +8,10 @@ template engine. Every `{if}` must be paired with a matching `{/if}`.
functions are recognized, such as *\|\|*, *or*, *&&*, *and*,
*is\_array()*, etc.
If securty is enabled, only PHP functions from `$php_functions` property
of the securty policy are allowed. See the
[Security](#advanced.features.security) section for details.
The following is a list of recognized qualifiers, which must be
separated from surrounding elements by spaces. Note that items listed in
\[brackets\] are optional. PHP equivalents are shown where applicable.
@@ -188,5 +188,5 @@ current template.
See also [template resources](#resources) and
See also [`{insert}`](#language.function.insert), [template resources](#resources) and
[componentized templates](#tips.componentized.templates).
@@ -0,0 +1,86 @@
{insert} {#language.function.insert}
========
> **Note**
>
> `{insert}` tags are deprecated from Smarty, and should not be used.
> Put your PHP logic in PHP scripts or plugin functions instead.
> **Note**
>
> As of Smarty 3.1 the `{insert}` tags are only available from
> [SmartyBC](#bc).
`{insert}` tags work much like [`{include}`](#language.function.include)
tags, except that `{insert}` tags are NOT cached when template
[caching](#caching) is enabled. They will be executed on every
invocation of the template.
Attribute Name Type Required Default Description
---------------- -------------- ---------- --------- ----------------------------------------------------------------------------------
name string Yes *n/a* The name of the insert function (insert\_`name`) or insert plugin
assign string No *n/a* The name of the template variable the output will be assigned to
script string No *n/a* The name of the php script that is included before the insert function is called
\[var \...\] \[var type\] No *n/a* variable to pass to insert function
Let\'s say you have a template with a banner slot at the top of the
page. The banner can contain any mixture of HTML, images, flash, etc. so
we can\'t just use a static link here, and we don\'t want this contents
cached with the page. In comes the {insert} tag: the template knows
\#banner\_location\_id\# and \#site\_id\# values (gathered from a
[config file](#config.files)), and needs to call a function to get the
banner contents.
{* example of fetching a banner *}
{insert name="getBanner" lid=#banner_location_id# sid=#site_id#}
{insert "getBanner" lid=#banner_location_id# sid=#site_id#} {* short-hand *}
In this example, we are using the name "getBanner" and passing the
parameters \#banner\_location\_id\# and \#site\_id\#. Smarty will look
for a function named insert\_getBanner() in your PHP application,
passing the values of \#banner\_location\_id\# and \#site\_id\# as the
first argument in an associative array. All {insert} function names in
your application must be prepended with \"insert\_\" to remedy possible
function name-space conflicts. Your insert\_getBanner() function should
do something with the passed values and return the results. These
results are then displayed in the template in place of the {insert} tag.
In this example, Smarty would call this function:
insert\_getBanner(array(\"lid\" =\> \"12345\",\"sid\" =\> \"67890\"));
and display the returned results in place of the {insert} tag.
- If you supply the `assign` attribute, the output of the `{insert}`
tag will be assigned to this template variable instead of being
output to the template.
> **Note**
>
> Assigning the output to a template variable isn\'t too useful with
> [caching](#variable.caching) enabled.
- If you supply the `script` attribute, this php script will be
included (only once) before the `{insert}` function is executed.
This is the case where the insert function may not exist yet, and a
php script must be included first to make it work.
The path can be either absolute, or relative to
[`$trusted_dir`](#variable.trusted.dir). If security is enabled,
then the script must be located in the `$trusted_dir` path of the
security policy. See the [Security](#advanced.features.security)
section for details.
The Smarty object is passed as the second argument. This way you can
reference and modify information in the Smarty object from within the
`{insert}` function.
If no PHP script can be found Smarty is looking for a corresponding
insert plugin.
> **Note**
>
> It is possible to have portions of the template not cached. If you
> have [caching](#caching) turned on, `{insert}` tags will not be
> cached. They will run dynamically every time the page is created, even
> within cached pages. This works good for things like banners, polls,
> live weather, search results, user feedback areas, etc.
See also [`{include}`](#language.function.include)
+3 -5
View File
@@ -143,9 +143,7 @@ the same vars, etc., we can do that in one place.
```php
<?php
use Smarty\Smarty;
class My_GuestBook extends Smarty {
class Smarty_GuestBook extends Smarty {
public function __construct()
{
@@ -163,9 +161,9 @@ class My_GuestBook extends Smarty {
}
```
Now, we can use `My_GuestBook` instead of `Smarty` in our scripts:
Now, we can use `Smarty_GuestBook` instead of `Smarty` in our scripts:
```php
$smarty = new My_GuestBook();
$smarty = new Smarty_GuestBook();
$smarty->assign('name','Ned');
$smarty->display('index.tpl');
```
+1
View File
@@ -37,6 +37,7 @@ and 480 for $height, the result is:
## Smarty for php developers
- [Charset Encoding](./programmers/charset.md)
- [Constants](./programmers/smarty-constants.md)
- [Smarty Class Variables](./programmers/api-variables.md)
- [Smarty Class Methods](./programmers/api-functions.md)
- [Caching](./programmers/caching.md)
@@ -10,14 +10,15 @@ output filters operate on the template output when it is executed.
Output filters can be either [registered](#api.register.filter) or
loaded from the [plugins directory](#variable.plugins.dir) by using the
[`loadFilter()`](#api.load.filter) method. Smarty will
[`loadFilter()`](#api.load.filter) method or by setting the
[`$autoload_filters`](#variable.autoload.filters) variable. Smarty will
pass the template output as the first argument, and expect the function
to return the result of the processing.
<?php
// put this in your application
function protect_email($tpl_output, \Smarty\Template\ $template)
function protect_email($tpl_output, Smarty_Internal_Template $template)
{
$tpl_output =
preg_replace('!(\S+)@([a-zA-Z0-9\.\-]+\.([a-zA-Z]{2,3}|[0-9]{1,3}))!',
@@ -37,5 +38,6 @@ to return the result of the processing.
See also [`registerFilter()`](#api.register.filter),
[`loadFilter()`](#api.load.filter),
[`$autoload_filters`](#variable.autoload.filters),
[postfilters](#advanced.features.postfilters) and
[`$plugins_dir`](#variable.plugins.dir).
@@ -5,14 +5,15 @@ Template postfilters are PHP functions that your templates are ran
through *after they are compiled*. Postfilters can be either
[registered](#api.register.filter) or loaded from the [plugins
directory](#variable.plugins.dir) by using the
[`loadFilter()`](#api.load.filter) function. Smarty will
[`loadFilter()`](#api.load.filter) function or by setting the
[`$autoload_filters`](#variable.autoload.filters) variable. Smarty will
pass the compiled template code as the first argument, and expect the
function to return the result of the processing.
<?php
// put this in your application
function add_header_comment($tpl_source, \Smarty\Template\ $template)
function add_header_comment($tpl_source, Smarty_Internal_Template $template)
{
return "<?php echo \"<!-- Created by Smarty! -->\n\"; ?>\n".$tpl_source;
}
@@ -8,7 +8,8 @@ putting in their templates, etc.
Prefilters can be either [registered](#api.register.filter) or loaded
from the [plugins directory](#variable.plugins.dir) by using
[`loadFilter()`](#api.load.filter) function.
[`loadFilter()`](#api.load.filter) function or by setting the
[`$autoload_filters`](#variable.autoload.filters) variable.
Smarty will pass the template source code as the first argument, and
expect the function to return the resulting template source code.
@@ -18,7 +19,7 @@ This will remove all the html comments in the template source.
<?php
// put this in your application
function remove_dw_comments($tpl_source, \Smarty\Template\ $template)
function remove_dw_comments($tpl_source, Smarty_Internal_Template $template)
{
return preg_replace("/<!--#.*-->/U",'',$tpl_source);
}
@@ -11,8 +11,14 @@ instance of the Smarty\_Security class. These are the possible settings:
- `$secure_dir` is an array of template directories that are
considered secure. [`$template_dir`](#variable.template.dir)
considered secure implicitly. The default is an empty array.
- `$trusted_uri` is an array of regular expressions matching URIs that
- `$trusted_dir` is an array of all directories that are considered
trusted. Trusted directories are where you keep php scripts that are
executed directly from the templates with
[`{insert}`](#language.function.insert.php). The default is an
empty array.
- `$trusted_uri` is an array of regular expressions matching URIs that
are considered trusted. This security directive used by
[`{fetch}`](#language.function.fetch) and
[`{html_image}`](#language.function.html.image). URIs passed to
@@ -47,6 +53,19 @@ instance of the Smarty\_Security class. These are the possible settings:
static classes. To disable access to all static classes set
\$static\_classes = null.
- `$php_functions` is an array of PHP functions that are considered
trusted and can be used from within template. To disable access to
all PHP functions set \$php\_functions = null. An empty array (
\$php\_functions = array() ) will allow all PHP functions. The
default is array(\'isset\', \'empty\', \'count\', \'sizeof\',
\'in\_array\', \'is\_array\',\'time\',\'nl2br\').
- `$php_modifiers` is an array of PHP functions that are considered
trusted and can be used from within template as modifier. To disable
access to all PHP modifier set \$php\_modifier = null. An empty
array ( \$php\_modifier = array() ) will allow all PHP functions.
The default is array(\'escape\',\'count\').
- `$streams` is an array of streams that are considered trusted and
can be used from within template. To disable access to all streams
set \$streams = null. An empty array ( \$streams = array() ) will
@@ -84,9 +103,13 @@ Smarty\_Security class or create an instance of it.
<?php
require 'Smarty.class.php';
class My_Security_Policy extends \Smarty\Security {
public $allow_constants = false;
class My_Security_Policy extends Smarty_Security {
// disable all PHP functions
public $php_functions = null;
// allow everthing as modifier
public $php_modifiers = array();
}
$smarty = new Smarty();
// enable security
@@ -95,9 +118,13 @@ Smarty\_Security class or create an instance of it.
<?php
require 'Smarty.class.php';
$smarty = new Smarty();
$my_security_policy = new \Smarty\Security($smarty);
$my_security_policy->allow_constants = false;
$my_security_policy = new Smarty_Security($smarty);
// disable all PHP functions
$my_security_policy->php_functions = null;
// allow everthing as modifier
$my_security_policy->php_modifiers = array();
// enable security
$smarty->enableSecurity($my_security_policy);
?>
+2
View File
@@ -31,6 +31,7 @@ Smarty Class Methods {#api.functions}
- [getConfigVars()](./api-functions/api-get-config-vars.md) — returns the given loaded config variable value
- [getPluginsDir()](./api-functions/api-get-plugins-dir.md) — return the directory where plugins are stored
- [getRegisteredObject()](./api-functions/api-get-registered-object.md) — returns a reference to a registered object
- [getTags()](./api-functions/api-get-tags.md) — return tags used by template
- [getTemplateDir()](./api-functions/api-get-template-dir.md) — return the directory where templates are stored
- [getTemplateVars()](./api-functions/api-get-template-vars.md) — returns assigned variable value(s)
- [isCached()](./api-functions/api-is-cached.md) — returns true if there is a valid cache for this template
@@ -54,6 +55,7 @@ Smarty Class Methods {#api.functions}
- [unregisterPlugin()](./api-functions/api-unregister-plugin.md) — dynamically unregister plugins
- [unregisterObject()](./api-functions/api-unregister-object.md) — dynamically unregister an object
- [unregisterResource()](./api-functions/api-unregister-resource.md) — dynamically unregister a resource plugin
- [testInstall()](./api-functions/api-test-install.md) — checks Smarty installation
> **Note**
>
@@ -31,9 +31,7 @@ PARAMETER.COMPILEID
<?php
use Smarty\Smarty;
include(SMARTY_DIR.'Smarty.class.php');
$smarty = new Smarty();
$smarty->setCaching(true);
@@ -0,0 +1,40 @@
getTags()
return tags used by template
Description
===========
string
getTags
object
template
This function returns an array of tagname/attribute pairs for all tags
used by the template. It uses the following parameters:
- `template` is the template object.
> **Note**
>
> This function is experimental.
<?php
include('Smarty.class.php');
$smarty = new Smarty;
// create template object
$tpl = $smarty->createTemplate('index.tpl');
// get tags
$tags = $smarty->getTags($tpl);
print_r($tags);
?>
@@ -22,8 +22,8 @@ string
compile\_id
- This only works if [`$caching`](#variable.caching) is set to one of
`\Smarty\Smarty::CACHING_LIFETIME_CURRENT` or
`\Smarty\Smarty::CACHING_LIFETIME_SAVED` to enable caching. See the [caching
`Smarty::CACHING_LIFETIME_CURRENT` or
`Smarty::CACHING_LIFETIME_SAVED` to enable caching. See the [caching
section](#caching) for more info.
- You can also pass a `$cache_id` as an optional second parameter in
@@ -18,7 +18,7 @@ string
name
The first argument specifies the type of the filter to load and can be
one of the following: `variable`, `pre`, `post` or `output`. The second argument
one of the following: `pre`, `post` or `output`. The second argument
specifies the `name` of the filter plugin.
@@ -37,5 +37,6 @@ specifies the `name` of the filter plugin.
See also [`registerFilter()`](#api.register.filter) and [advanced
See also [`registerFilter()`](#api.register.filter),
[`$autoload_filters`](#variable.autoload.filters) and [advanced
features](#advanced.features).
@@ -15,7 +15,7 @@ handler merely inspects `$errno` and `$errfile` to determine if the
given error was produced deliberately and must be ignored, or should be
passed on to the next error handler.
`\Smarty\Smarty::unmuteExpectedErrors()` removes the current error handler.
`Smarty::unmuteExpectedErrors()` removes the current error handler.
Please note, that if you\'ve registered any custom error handlers after
the muteExpectedErrors() call, the unmute will not remove Smarty\'s
muting error handler, but the one registered last.
@@ -31,7 +31,7 @@ how to create custom CacheResources.
<?php
$smarty->registerCacheResource('mysql', new My_CacheResource_Mysql());
$smarty->registerCacheResource('mysql', new Smarty_CacheResource_Mysql());
?>
@@ -37,7 +37,7 @@ plugin types.
* @param string $name name of the undefined tag
* @param string $type tag type (e.g. Smarty::PLUGIN_FUNCTION, Smarty::PLUGIN_BLOCK,
Smarty::PLUGIN_COMPILER, Smarty::PLUGIN_MODIFIER, Smarty::PLUGIN_MODIFIERCOMPILER)
* @param \Smarty\Template\ $template template object
* @param Smarty_Internal_Template $template template object
* @param string &$callback returned function name
* @param string &$script optional returned script filepath if function is external
* @param bool &$cacheable true by default, set to false if plugin is not cachable (Smarty >= 3.1.8)
@@ -38,7 +38,8 @@ filters](#advanced.features.outputfilters) for more information on how
to set up an output filter function.
See also [`unregisterFilter()`](#api.unregister.filter),
[`loadFilter()`](#api.load.filter), [template pre
[`loadFilter()`](#api.load.filter),
[`$autoload_filters`](#variable.autoload.filters), [template pre
filters](#advanced.features.prefilters) [template post
filters](#advanced.features.postfilters) [template output
filters](#advanced.features.outputfilters) section.
@@ -32,9 +32,9 @@ cache\_attrs
This method registers functions or methods defined in your script as
plugin. It uses the following parameters:
- `cacheable` can be omitted in most cases. See
- `cacheable` and `cache_attrs` can be omitted in most cases. See
[controlling cacheability of plugins output](#caching.cacheable) on
how to use this properly.
how to use them properly.
<!-- -->
@@ -37,7 +37,7 @@ information on how to setup a function for fetching templates.
<?php
$smarty->registerResource('mysql', new My_Resource_Mysql());
$smarty->registerResource('mysql', new Smarty_Resource_Mysql());
?>
@@ -55,4 +55,5 @@ And the php script
See also [`display()`](#api.display), [`fetch()`](#api.fetch),
and [`{include}`](#language.function.include)
[`{include}`](#language.function.include) and
[`{insert}`](#language.function.insert)
+6
View File
@@ -4,7 +4,9 @@ Smarty Class Variables {#api.variables}
These are all of the available Smarty class variables. You can access
them directly, or use the corresponding setter/getter methods.
- [$allow_php_templates](./api-variables/variable-allow-php-templates.md)
- [$auto_literal](./api-variables/variable-auto-literal.md)
- [$autoload_filters](./api-variables/variable-autoload-filters.md)
- [$cache_dir](./api-variables/variable-cache-dir.md)
- [$cache_id](./api-variables/variable-cache-id.md)
- [$cache_lifetime](./api-variables/variable-cache-lifetime.md)
@@ -29,6 +31,7 @@ them directly, or use the corresponding setter/getter methods.
- [$default_resource_type](./api-variables/variable-default-resource-type.md)
- [$default_config_handler_func](./api-variables/variable-default-config-handler-func.md)
- [$default_template_handler_func](./api-variables/variable-default-template-handler-func.md)
- [$direct_access_security](./api-variables/variable-direct-access-security.md)
- [$error_reporting](./api-variables/variable-error-reporting.md)
- [$escape_html](./api-variables/variable-escape-html.md)
- [$force_cache](./api-variables/variable-force-cache.md)
@@ -36,9 +39,12 @@ them directly, or use the corresponding setter/getter methods.
- [$left_delimiter](./api-variables/variable-left-delimiter.md)
- [$locking_timeout](./api-variables/variable-locking-timeout.md)
- [$merge_compiled_includes](./api-variables/variable-merge-compiled-includes.md)
- [$plugins_dir](./api-variables/variable-plugins-dir.md)
- [$right_delimiter](./api-variables/variable-right-delimiter.md)
- [$smarty_debug_id](./api-variables/variable-smarty-debug-id.md)
- [$template_dir](./api-variables/variable-template-dir.md)
- [$trusted_dir](./api-variables/variable-trusted-dir.md)
- [$use_include_path](./api-variables/variable-use-include-path.md)
- [$use_sub_dirs](./api-variables/variable-use-sub-dirs.md)
> **Note**
@@ -0,0 +1,18 @@
\$allow\_php\_templates {#variable.allow.php.templates}
=======================
By default the PHP template file resource is disabled. Setting
`$allow_php_templates` to TRUE will enable PHP template files.
::: {.informalexample}
<?php
$smarty->allow_php_templates = true;
?>
:::
> **Note**
>
> The PHP template file resource is an undocumented deprecated feature.
@@ -0,0 +1,21 @@
\$autoload\_filters {#variable.autoload.filters}
===================
If there are some filters that you wish to load on every template
invocation, you can specify them using this variable and Smarty will
automatically load them for you. The variable is an associative array
where keys are filter types and values are arrays of the filter names.
For example:
::: {.informalexample}
<?php
$smarty->autoload_filters = array('pre' => array('trim', 'stamp'),
'output' => array('convert'));
?>
:::
See also [`registerFilter()`](#api.register.filter) and
[`loadFilter()`](#api.load.filter)
@@ -5,8 +5,8 @@ This is the length of time in seconds that a template cache is valid.
Once this time has expired, the cache will be regenerated.
- `$caching` must be turned on (either
\Smarty\Smarty::CACHING\_LIFETIME\_CURRENT or
\Smarty\Smarty::CACHING\_LIFETIME\_SAVED) for `$cache_lifetime` to have any
Smarty::CACHING\_LIFETIME\_CURRENT or
Smarty::CACHING\_LIFETIME\_SAVED) for `$cache_lifetime` to have any
purpose.
- A `$cache_lifetime` value of -1 will force the cache to never
@@ -14,11 +14,11 @@ Once this time has expired, the cache will be regenerated.
- A value of 0 will cause the cache to always regenerate (good for
testing only, to disable caching a more efficient method is to set
[`$caching`](#variable.caching) = \Smarty\Smarty::CACHING\_OFF).
[`$caching`](#variable.caching) = Smarty::CACHING\_OFF).
- If you want to give certain templates their own cache lifetime, you
could do this by setting [`$caching`](#variable.caching) =
\Smarty\Smarty::CACHING\_LIFETIME\_SAVED, then set `$cache_lifetime` to a
Smarty::CACHING\_LIFETIME\_SAVED, then set `$cache_lifetime` to a
unique value just before calling [`display()`](#api.display) or
[`fetch()`](#api.fetch).
@@ -4,7 +4,8 @@
If set to TRUE, Smarty will respect the If-Modified-Since header sent
from the client. If the cached file timestamp has not changed since the
last visit, then a `'304: Not Modified'` header will be sent instead of
the content.
the content. This works only on cached content without
[`{insert}`](#language.function.insert) tags.
See also [`$caching`](#variable.caching),
[`$cache_lifetime`](#variable.cache.lifetime), and the [caching
@@ -3,21 +3,21 @@
This tells Smarty whether or not to cache the output of the templates to
the [`$cache_dir`](#variable.cache.dir). By default this is set to the
constant \Smarty\Smarty::CACHING\_OFF. If your templates consistently generate
constant Smarty::CACHING\_OFF. If your templates consistently generate
the same content, it is advisable to turn on `$caching`, as this may
result in significant performance gains.
You can also have [multiple](#caching.multiple.caches) caches for the
same template.
- A constant value of \Smarty\Smarty::CACHING\_LIFETIME\_CURRENT or
\Smarty\Smarty ::CACHING\_LIFETIME\_SAVED enables caching.
- A constant value of Smarty::CACHING\_LIFETIME\_CURRENT or
Smarty::CACHING\_LIFETIME\_SAVED enables caching.
- A value of \Smarty\Smarty::CACHING\_LIFETIME\_CURRENT tells Smarty to use
- A value of Smarty::CACHING\_LIFETIME\_CURRENT tells Smarty to use
the current [`$cache_lifetime`](#variable.cache.lifetime) variable
to determine if the cache has expired.
- A value of \Smarty\Smarty::CACHING\_LIFETIME\_SAVED tells Smarty to use the
- A value of Smarty::CACHING\_LIFETIME\_SAVED tells Smarty to use the
[`$cache_lifetime`](#variable.cache.lifetime) value at the time the
cache was generated. This way you can set the
[`$cache_lifetime`](#variable.cache.lifetime) just before
@@ -18,7 +18,7 @@ enabled, then the cache files will get regenerated if an involved
template file or config file was updated.
As of Smarty 3.1 `$compile_check` can be set to the value
`\Smarty\Smarty::COMPILECHECK_CACHEMISS`. This enables Smarty to revalidate the
`Smarty::COMPILECHECK_CACHEMISS`. This enables Smarty to revalidate the
compiled template, once a cache file is regenerated. So if there was a
cached template, but it\'s expired, Smarty will run a single
compile\_check before regenerating the cache.
@@ -2,7 +2,8 @@
============
This is the name of the template file used for the debugging console. By
default, it is named `debug.tpl` and is located in `src/debug.tpl`.
default, it is named `debug.tpl` and is located in the
[`SMARTY_DIR`](#constant.smarty.dir).
See also [`$debugging`](#variable.debugging) and the [debugging
console](#chapter.debugging.console) section.
@@ -8,7 +8,7 @@ resource.
>
> The default handler is currently only invoked for file resources. It
> is not triggered when the resource itself cannot be found, in which
> case a \Smarty\Exception is thrown.
> case a SmartyException is thrown.
<?php
@@ -8,7 +8,7 @@ resource.
>
> The default handler is currently only invoked for file resources. It
> is not triggered when the resource itself cannot be found, in which
> case a \Smarty\Exception is thrown.
> case a SmartyException is thrown.
<?php
@@ -0,0 +1,13 @@
\$direct\_access\_security {#variable.direct.access.security}
==========================
Direct access security inhibits direct browser access to compiled or
cached template files.
Direct access security is enabled by default. To disable it set
`$direct_access_security` to FALSE.
> **Note**
>
> This is a compile time option. If you change the setting you must make
> sure that the templates get recompiled.
@@ -7,7 +7,7 @@ When this value is set to a non-null-value it\'s value is used as php\'s
Smarty 3.1.2 introduced the
[`muteExpectedErrors()`](#api.mute.expected.errors) function. Calling
`\Smarty\Smarty::muteExpectedErrors();` after setting up custom error handling
`Smarty::muteExpectedErrors();` after setting up custom error handling
will ensure that warnings and notices (deliberately) produced by Smarty
will not be passed to other custom error handlers. If your error logs
are filling up with warnings regarding `filemtime()` or `unlink()`
@@ -0,0 +1,28 @@
\$plugins\_dir {#variable.plugins.dir}
==============
This is the directory or directories where Smarty will look for the
plugins that it needs. Default is `plugins/` under the
[`SMARTY_DIR`](#constant.smarty.dir). If you supply a relative path,
Smarty will first look under the [`SMARTY_DIR`](#constant.smarty.dir),
then relative to the current working directory, then relative to the PHP
include\_path. If `$plugins_dir` is an array of directories, Smarty will
search for your plugin in each plugin directory **in the order they are
given**.
> **Note**
>
> For best performance, do not setup your `$plugins_dir` to have to use
> the PHP include path. Use an absolute pathname, or a path relative to
> `SMARTY_DIR` or the current working directory.
> **Note**
>
> As of Smarty 3.1 the attribute \$plugins\_dir is no longer accessible
> directly. Use [`getPluginsDir()`](#api.get.plugins.dir),
> [`setPluginsDir()`](#api.set.plugins.dir) and
> [`addPluginsDir()`](#api.add.plugins.dir) instead.
See also [`getPluginsDir()`](#api.get.plugins.dir),
[`setPluginsDir()`](#api.set.plugins.dir) and
[`addPluginsDir()`](#api.add.plugins.dir).
@@ -15,12 +15,22 @@ found.
> document root.
> **Note**
>
> If the directories known to `$template_dir` are relative to
> directories known to the
> [include\_path](&url.php-manual;ini.core.php#ini.include-path) you
> need to activate the [`$use_include_path`](#variable.use.include.path)
> option.
> **Note**
>
> As of Smarty 3.1 the attribute \$template\_dir is no longer accessible
> directly. Use [`getTemplateDir()`](#api.get.template.dir),
> [`setTemplateDir()`](#api.set.template.dir) and
> [`addTemplateDir()`](#api.add.template.dir) instead.
See also [`Template Resources`](#resources),
[`$use_include_path`](#variable.use.include.path),
[`getTemplateDir()`](#api.get.template.dir),
[`setTemplateDir()`](#api.set.template.dir) and
[`addTemplateDir()`](#api.add.template.dir).
@@ -0,0 +1,8 @@
\$trusted\_dir {#variable.trusted.dir}
==============
`$trusted_dir` is only for use when security is enabled. This is an
array of all directories that are considered trusted. Trusted
directories are where you keep php scripts that are executed directly
from the templates with
[`{insert}`](#language.function.insert.php).
@@ -0,0 +1,49 @@
\$use\_include\_path {#variable.use.include.path}
====================
This tells smarty to respect the
[include\_path](&url.php-manual;ini.core.php#ini.include-path) within
the [`File Template Resource`](#resources.file) handler and the plugin
loader to resolve the directories known to
[`$template_dir`](#variable.template.dir). The flag also makes the
plugin loader check the include\_path for
[`$plugins_dir`](#variable.plugins.dir).
> **Note**
>
> You should not design your applications to rely on the include\_path,
> as this may - depending on your implementation - slow down your system
> (and Smarty) considerably.
If use\_include\_path is enabled, file discovery for
[`$template_dir`](#variable.template.dir) and
[`$plugins_dir`](#variable.plugins.dir) work as follows.
- For each element `$directory` in array (\$template\_dir or
\$plugins\_dir) do
- Test if requested file is in `$directory` relative to the [current
working directory](&url.php-manual;function.getcwd.php). If file
found, return it.
- For each `$path` in include\_path do
- Test if requested file is in `$directory` relative to the `$path`
(possibly relative to the [current working
directory](&url.php-manual;function.getcwd.php)). If file found,
return it.
- Try default\_handler or fail.
This means that whenever a directory/file relative to the current
working directory is encountered, it is preferred over anything
potentially accessible through the include\_path.
> **Note**
>
> Smarty does not filter elements of the include\_path. That means a
> \".:\" within your include path will trigger the current working
> directory lookup twice.
See also [`Template Resources`](#resources) and
[`$template_dir`](#variable.template.dir)
+50 -2
View File
@@ -76,14 +76,62 @@ third parameter to [`registerPlugin()`](#api.register.plugin) is called
When registering a plugin with `$cacheable=false` the plugin is called
everytime the page is displayed, even if the page comes from the cache.
The plugin function behaves a little like an
[`{insert}`](#plugins.inserts) function.
> **Note**
>
> The `$cacheable` status will affect the compiled template code. If you
> The `$cacheable` status will effect the compiled template code. If you
> change the status you must manually delete existing compiled and
> cached template files to force a recompile.
Example `index.php`:
In contrast to [`{insert}`](#plugins.inserts) the attributes to the
plugins are not cached by default. They can be declared to be cached
with the fourth parameter `$cache_attrs`. `$cache_attrs` is an array of
attribute-names that should be cached, so the plugin-function get value
as it was the time the page was written to cache everytime it is fetched
from the cache.
<?php
$smarty->setCaching(Smarty::CACHING_LIFETIME_CURRENT);
function remaining_seconds($params, $smarty) {
$remain = $params['endtime'] - time();
if($remain >= 0){
return $remain . ' second(s)';
}else{
return 'done';
}
}
$smarty->registerPlugin('function','remaining', 'remaining_seconds', false, array('endtime'));
if (!$smarty->isCached('index.tpl')) {
// fetch $obj from db and assign...
$smarty->assignByRef('obj', $obj);
}
$smarty->display('index.tpl');
?>
where `index.tpl` is:
Time Remaining: {remaining endtime=$obj->endtime}
The number of seconds till the endtime of `$obj` is reached changes on
each display of the page, even if the page is cached. Since the endtime
attribute is cached the object only has to be pulled from the database
when page is written to the cache but not on subsequent requests of the
page.
index.php:
<?php
$smarty->setCaching(Smarty::CACHING_LIFETIME_CURRENT);
+8 -8
View File
@@ -17,11 +17,11 @@ faster storage engine, centralize the cache to be accessible to multiple
servers.
Smarty allows CacheResource implementations to use one of the APIs
`\Smarty\Cacheresource\Custom` or `\Smarty\Cacheresource\KeyValueStore`.
`\Smarty\Cacheresource\Custom` is a simple API directing all read, write,
`Smarty_CacheResource_Custom` or `Smarty_CacheResource_KeyValueStore`.
`Smarty_CacheResource_Custom` is a simple API directing all read, write,
clear calls to your implementation. This API allows you to store
wherever and however you deem fit. The
`\Smarty\Cacheresource\KeyValueStore` API allows you to turn any \"dumb\"
`Smarty_CacheResource_KeyValueStore` API allows you to turn any \"dumb\"
KeyValue-Store (like APC, Memcache, ...) into a full-featured
CacheResource implementation. That is, everything around deep
cache-groups like \"a\|b\|c\" is being handled for you in way that
@@ -63,10 +63,10 @@ to invoke your custom CacheResource implementation.
* INDEX(`modified`)
* ) ENGINE = InnoDB;</pre>
*
* @package CacheResource-examples
* @author Rodney Rehm
*/
class My_CacheResource_Mysql extends \Smarty\Cacheresource\Custom {
class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom {
// PDO instance
protected $db;
protected $fetch;
@@ -77,7 +77,7 @@ to invoke your custom CacheResource implementation.
try {
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty", "smarty");
} catch (PDOException $e) {
throw new \Smarty\Exception('Mysql Resource failed: ' . $e->getMessage());
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, content FROM output_cache WHERE id = :id');
$this->fetchTimestamp = $this->db->prepare('SELECT modified FROM output_cache WHERE id = :id');
@@ -211,10 +211,10 @@ to invoke your custom CacheResource implementation.
* Note that memcache has a limitation of 256 characters per cache-key.
* To avoid complications all cache-keys are translated to a sha1 hash.
*
* @package CacheResource-examples
* @author Rodney Rehm
*/
class My_CacheResource_Memcache extends \Smarty\Cacheresource\KeyValueStore {
class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore {
/**
* memcache instance
* @var Memcache
+10 -7
View File
@@ -3,7 +3,7 @@ Setting Up Caching {#caching.setting.up}
The first thing to do is enable caching by setting
[`$caching`](#variable.caching) to one of
`\Smarty\Smarty::CACHING_LIFETIME_CURRENT` or `Smarty::CACHING_LIFETIME_SAVED`.
`Smarty::CACHING_LIFETIME_CURRENT` or `Smarty::CACHING_LIFETIME_SAVED`.
<?php
@@ -36,7 +36,7 @@ Each cached page has a limited lifetime determined by
seconds, or one hour. After that time expires, the cache is regenerated.
It is possible to give individual caches their own expiration time by
setting [`$caching`](#variable.caching) to
`\Smarty\Smarty::CACHING_LIFETIME_SAVED`. See
`Smarty::CACHING_LIFETIME_SAVED`. See
[`$cache_lifetime`](#variable.cache.lifetime) for more details.
@@ -92,7 +92,7 @@ however this also seriously degrades performance.
[`$force_compile`](#variable.force.compile) is meant to be used for
[debugging](#chapter.debugging.console) purposes. The appropriate way to
disable caching is to set [`$caching`](#variable.caching) to
\Smarty\Smarty::CACHING\_OFF.
Smarty::CACHING\_OFF.
The [`isCached()`](#api.is.cached) function can be used to test if a
template has a valid cache or not. If you have a cached template that
@@ -118,13 +118,16 @@ process.
You can keep parts of a page dynamic (disable caching) with the
[`{nocache}{/nocache}`](#language.function.nocache) block function, or by using the
[`{nocache}{/nocache}`](#language.function.nocache) block function, the
[`{insert}`](#language.function.insert) function, or by using the
`nocache` parameter for most template functions.
Let\'s say the whole page can be cached except for a banner that is
displayed down the side of the page. By using a [`{nocache}{/nocache}`](#language.function.nocache)
block for the banner, you can
keep this element dynamic within the cached content.
displayed down the side of the page. By using the
[`{insert}`](#language.function.insert) function for the banner, you can
keep this element dynamic within the cached content. See the
documentation on [`{insert}`](#language.function.insert) for more
details and examples.
You can clear all the cache files with the
[`clearAllCache()`](#api.clear.all.cache) function, or individual cache
+8 -3
View File
@@ -5,8 +5,10 @@ Charset Encoding {#charset.encoding}
================
There are a variety of encodings for textual data, ISO-8859-1 (Latin1)
and UTF-8 being the most popular. Unless you change `\Smarty\Smarty::$_CHARSET`,
Smarty recognizes `UTF-8` as the internal charset.
and UTF-8 being the most popular. Unless you change `Smarty::$_CHARSET`,
Smarty recognizes `UTF-8` as the internal charset if
[Multibyte String](https://www.php.net/mbstring) is available,
`ISO-8859-1` if not.
> **Note**
>
@@ -24,7 +26,10 @@ Smarty recognizes `UTF-8` as the internal charset.
> **Note**
>
> Smarty\'s internals and core plugins are truly UTF-8 compatible since
> Smarty 3.1.
> Smarty 3.1. To achieve unicode compatibility, the [Multibyte
> String](https://www.php.net/mbstring) PECL is required. Unless your PHP
> environment offers this package, Smarty will not be able to offer
> full-scale UTF-8 compatibility.
// use japanese character encoding
+1
View File
@@ -13,6 +13,7 @@ Extending Smarty With Plugins {#plugins}
- [Prefilters/Postfilters](./plugins/plugins-prefilters-postfilters.md)
- [Output Filters](./plugins/plugins-outputfilters.md)
- [Resources](./plugins/plugins-resources.md)
- [Inserts](./plugins/plugins-inserts.md)
Version 2.0 introduced the plugin architecture that is used for almost
all the customizable functionality of Smarty. This includes:
@@ -60,6 +60,12 @@ cannot have both custom function `{func}` and block function
function implementation is called again with the new block contents
in the parameter `$content`.
If you have nested block functions, it\'s possible to find out what the
parent block function is by accessing `$smarty->_tag_stack` variable.
Just do a [`var_dump()`](&url.php-manual;var_dump) on it and the
structure should be apparent.
<?php
/*
* Smarty plugin
@@ -70,7 +76,7 @@ cannot have both custom function `{func}` and block function
* Purpose: translate a block of text
* -------------------------------------------------------------
*/
function smarty_block_translate($params, $content, \Smarty\Template $template, &$repeat)
function smarty_block_translate($params, $content, Smarty_Internal_Template $template, &$repeat)
{
// only output on the closing tag
if(!$repeat){
@@ -40,7 +40,7 @@ some other Smarty-provided functionality, it can use the supplied
* Purpose: outputs a random magic answer
* -------------------------------------------------------------
*/
function smarty_function_eightball($params, \Smarty\Template\ $template)
function smarty_function_eightball($params, Smarty_Internal_Template $template)
{
$answers = array('Yes',
'No',
@@ -71,7 +71,7 @@ which can be used in the template as:
* Purpose: assign a value to a template variable
* -------------------------------------------------------------
*/
function smarty_function_assign($params, \Smarty\Template\ $template)
function smarty_function_assign($params, Smarty_Internal_Template $template)
{
if (empty($params['var'])) {
trigger_error("assign: missing 'var' parameter");
@@ -0,0 +1,48 @@
Inserts {#plugins.inserts}
=======
Insert plugins are used to implement functions that are invoked by
[`{insert}`](#language.function.insert) tags in the template.
string
smarty\_insert\_
name
array
\$params
object
\$template
The first parameter to the function is an associative array of
attributes passed to the insert.
The insert function is supposed to return the result which will be
substituted in place of the `{insert}` tag in the template.
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* File: insert.time.php
* Type: time
* Name: time
* Purpose: Inserts current date/time according to format
* -------------------------------------------------------------
*/
function smarty_insert_time($params, Smarty_Internal_Template $template)
{
if (empty($params['format'])) {
trigger_error("insert time: missing 'format' parameter");
return;
}
return strftime($params['format']);
}
?>
@@ -28,6 +28,8 @@ in order to be located by Smarty.
- resource
- insert
- And `name` should be a valid identifier; letters, numbers, and
underscores only, see [php
variables](&url.php-manual;language.variables).
@@ -35,7 +35,7 @@ and return the results.
* a simple protection against spambots
* -------------------------------------------------------------
*/
function smarty_outputfilter_protect_email($output, \Smarty\Template\ $template)
function smarty_outputfilter_protect_email($output, Smarty_Internal_Template $template)
{
return preg_replace('!(\S+)@([a-zA-Z0-9\.\-]+\.([a-zA-Z]{2,3}|[0-9]{1,3}))!',
'$1%40$2', $output);
@@ -57,7 +57,7 @@ of this code.
* Purpose: Convert html tags to be lowercase.
* -------------------------------------------------------------
*/
function smarty_prefilter_pre01($source, \Smarty\Template\ $template)
function smarty_prefilter_pre01($source, Smarty_Internal_Template $template)
{
return preg_replace('!<(\w+)[^>]+>!e', 'strtolower("$1")', $source);
}
@@ -76,7 +76,7 @@ of this code.
* Purpose: Output code that lists all current template vars.
* -------------------------------------------------------------
*/
function smarty_postfilter_post01($compiled, \Smarty\Template\ $template)
function smarty_postfilter_post01($compiled, Smarty_Internal_Template $template)
{
$compiled = "<pre>\n<?php print_r(\$template->getTemplateVars()); ?>\n</pre>" . $compiled;
return $compiled;
+10 -10
View File
@@ -12,20 +12,20 @@ will be able to access that resource by prepending its name to the
template you\'re addressing: `foobarxyz:yourtemplate.tpl`.
If a Resource\'s templates should not be run through the Smarty
compiler, the Custom Resource may extend `\Smarty\Resource\UncompiledPlugin`.
compiler, the Custom Resource may extend `Smarty_Resource_Uncompiled`.
The Resource Handler must then implement the function
`renderUncompiled(\Smarty\Template $_template)`. `$_template` is
`renderUncompiled(Smarty_Internal_Template $_template)`. `$_template` is
a reference to the current template and contains all assigned variables
which the implementor can access via
`$_template->getSmarty()->getTemplateVars()`. These Resources simply echo
`$_template->smarty->getTemplateVars()`. These Resources simply echo
their rendered content to the output stream. The rendered output will be
output-cached if the Smarty instance was configured accordingly. See
`src/Resource/PhpPlugin.php` for an example.
`libs/sysplugins/smarty_internal_resource_php.php` for an example.
If the Resource\'s compiled templates should not be cached on disk, the
Custom Resource may extend `\Smarty\Resource\RecompiledPlugin`. These Resources
Custom Resource may extend `Smarty_Resource_Recompiled`. These Resources
are compiled every time they are accessed. This may be an expensive
overhead. See `src/Resource/StringEval.php` for an
overhead. See `libs/sysplugins/smarty_internal_resource_eval.php` for an
example.
@@ -48,10 +48,10 @@ example.
* Demo data:
* <pre>INSERT INTO `templates` (`name`, `modified`, `source`) VALUES ('test.tpl', "2010-12-25 22:00:00", '{$x="hello world"}{$x}');</pre>
*
* @package Resource-examples
* @author Rodney Rehm
*/
class My_Resource_Mysql extends \Smarty\Resource\CustomPlugin {
class Smarty_Resource_Mysql extends Smarty_Resource_Custom {
// PDO instance
protected $db;
// prepared fetch() statement
@@ -63,7 +63,7 @@ example.
try {
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty", "smarty");
} catch (PDOException $e) {
throw new \Smarty\Exception('Mysql Resource failed: ' . $e->getMessage());
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
$this->mtime = $this->db->prepare('SELECT modified FROM templates WHERE name = :name');
@@ -109,7 +109,7 @@ example.
require_once 'libs/Smarty.class.php';
$smarty = new Smarty();
$smarty->registerResource('mysql', new My_Resource_Mysql());
$smarty->registerResource('mysql', new Smarty_Resource_Mysql());
// using resource from php script
$smarty->display("mysql:index.tpl");
+17 -1
View File
@@ -8,7 +8,23 @@ functions.
For the plugins that are registered at runtime, the name of the plugin
function(s) does not have to follow the naming convention.
If a plugin depends on some functionality provided by another plugin (as
is the case with some plugins bundled with Smarty), then the proper way
to load the needed plugin is this:
<?php
function smarty_function_yourPlugin(array $params, Smarty_Internal_Template $template)
{
// load plugin depended upon
$template->smarty->loadPlugin('smarty_shared_make_timestamp');
// plugin code
}
?>
As a general rule, the currently evaluated template\'s
Smarty\_Internal\_Template object is always passed to the plugins as the
last parameter with two exceptions:
@@ -34,10 +34,10 @@ on the functions you are supposed to provide.
* Demo data:
* <pre>INSERT INTO `templates` (`name`, `modified`, `source`) VALUES ('test.tpl', "2010-12-25 22:00:00", '{$x="hello world"}{$x}');</pre>
*
* @package Resource-examples
* @author Rodney Rehm
*/
class My_Resource_Mysql extends \Smarty\Resource\Custom {
class Smarty_Resource_Mysql extends Smarty_Resource_Custom {
// PDO instance
protected $db;
// prepared fetch() statement
@@ -49,7 +49,7 @@ on the functions you are supposed to provide.
try {
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty", "smarty");
} catch (PDOException $e) {
throw new \Smarty\Exception('Mysql Resource failed: ' . $e->getMessage());
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
$this->mtime = $this->db->prepare('SELECT modified FROM templates WHERE name = :name');
@@ -95,7 +95,7 @@ on the functions you are supposed to provide.
require_once 'libs/Smarty.class.php';
$smarty = new Smarty();
$smarty->registerResource('mysql', new My_Resource_Mysql());
$smarty->registerResource('mysql', new Smarty_Resource_Mysql());
// using resource from php script
$smarty->display("mysql:index.tpl");
@@ -11,6 +11,12 @@ If the file resource cannot find the requested template, the
[`$default_template_handler_func`](#variable.default.template.handler.func)
is invoked.
> **Note**
>
> As of Smarty 3.1 the file resource no longer walks through the
> [include\_path](&url.php-manual;ini.core.php#ini.include-path) unless
> [`$use_include_path` is activated](#variable.use.include.path)
Templates from \$template\_dir {#templates.from.template.dir}
------------------------------
@@ -44,10 +44,10 @@ on the functions you are supposed to provide.
* Demo data:
* <pre>INSERT INTO `templates` (`name`, `modified`, `source`) VALUES ('test.tpl', "2010-12-25 22:00:00", '{$x="hello world"}{$x}');</pre>
*
* @package Resource-examples
* @author Rodney Rehm
*/
class My_Resource_Mysql extends \Smarty\Resource\Custom {
class Smarty_Resource_Mysql extends Smarty_Resource_Custom {
// PDO instance
protected $db;
// prepared fetch() statement
@@ -59,7 +59,7 @@ on the functions you are supposed to provide.
try {
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty", "smarty");
} catch (PDOException $e) {
throw new \Smarty\Exception('Mysql Resource failed: ' . $e->getMessage());
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
$this->mtime = $this->db->prepare('SELECT modified FROM templates WHERE name = :name');
@@ -105,7 +105,7 @@ on the functions you are supposed to provide.
require_once 'libs/Smarty.class.php';
$smarty = new Smarty();
$smarty->registerResource('mysql', new My_Resource_Mysql());
$smarty->registerResource('mysql', new Smarty_Resource_Mysql());
// using resource from php script
$smarty->display("mysql:index.tpl");
+26
View File
@@ -0,0 +1,26 @@
Constants {#smarty.constants}
=========
SMARTY\_DIR {#constant.smarty.dir}
===========
This is the **full system path** to the location of the Smarty class
files. If this is not defined in your script, then Smarty will attempt
to determine the appropriate value automatically. If defined, the path
**must end with a trailing slash/**.
<?php
// set path to Smarty directory *nix style
define('SMARTY_DIR', '/usr/local/lib/php/Smarty-v.e.r/libs/');
// path to Smarty windows style
define('SMARTY_DIR', 'c:/webroot/libs/Smarty-v.e.r/libs/');
// include the smarty class, note 'S' is upper case
require_once(SMARTY_DIR . 'Smarty.class.php');
?>
See also [`$smarty.const`](../designers/language-variables/language-variables-smarty.md).
@@ -1,9 +1,6 @@
<?php
namespace Smarty\Lexer;
/**
* Smarty Internal Plugin ConfigfileLexer
* Smarty Internal Plugin Configfilelexer
*
* This is the lexer to break the config file source into tokens
* @package Smarty
@@ -11,16 +8,16 @@ namespace Smarty\Lexer;
* @author Uwe Tews
*/
/**
* ConfigfileLexer
* Smarty_Internal_Configfilelexer
*
* This is the config file lexer.
* It is generated from the ConfigfileLexer.plex file
* It is generated from the smarty_internal_configfilelexer.plex file
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
class ConfigfileLexer
class Smarty_Internal_Configfilelexer
{
/**
* Source
@@ -73,7 +70,7 @@ class ConfigfileLexer
/**
* compiler object
*
* @var \Smarty\Compiler\Configfile
* @var Smarty_Internal_Config_File_Compiler
*/
private $compiler = null;
/**
@@ -125,9 +122,9 @@ class ConfigfileLexer
* constructor
*
* @param string $data template source
* @param \Smarty\Compiler\Configfile $compiler
* @param Smarty_Internal_Config_File_Compiler $compiler
*/
public function __construct($data, \Smarty\Compiler\Configfile $compiler)
public function __construct($data, Smarty_Internal_Config_File_Compiler $compiler)
{
$this->data = $data . "\n"; //now all lines are \n-terminated
$this->dataLength = strlen($data);
@@ -182,31 +179,31 @@ naked_string = /[^\n]+?(?=[ \t\r]*\n)/
%statename START
commentstart {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_COMMENTSTART;
$this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
$this->yypushstate(self::COMMENT);
}
openB {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_OPENB;
$this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
$this->yypushstate(self::SECTION);
}
closeB {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_CLOSEB;
$this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
}
equal {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_EQUAL;
$this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
$this->yypushstate(self::VALUE);
}
whitespace {
return false;
}
newline {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_NEWLINE;
$this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
}
id {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_ID;
$this->token = Smarty_Internal_Configfileparser::TPC_ID;
}
text {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_OTHER;
$this->token = Smarty_Internal_Configfileparser::TPC_OTHER;
}
*/
@@ -218,23 +215,23 @@ whitespace {
return false;
}
float {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_FLOAT;
$this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
$this->yypopstate();
}
int {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_INT;
$this->token = Smarty_Internal_Configfileparser::TPC_INT;
$this->yypopstate();
}
tripple_quotes {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_TRIPPLE_QUOTES;
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
$this->yypushstate(self::TRIPPLE);
}
single_quoted_string {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_SINGLE_QUOTED_STRING;
$this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
$this->yypopstate();
}
double_quoted_string {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_DOUBLE_QUOTED_STRING;
$this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
$this->yypopstate();
}
maybe_bool {
@@ -243,16 +240,16 @@ maybe_bool {
$this->yypushstate(self::NAKED_STRING_VALUE);
return true; //reprocess in new state
} else {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_BOOL;
$this->token = Smarty_Internal_Configfileparser::TPC_BOOL;
$this->yypopstate();
}
}
naked_string {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_NAKED_STRING;
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
$this->yypopstate();
}
newline {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_NAKED_STRING;
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
$this->value = '';
$this->yypopstate();
}
@@ -263,7 +260,7 @@ newline {
%statename NAKED_STRING_VALUE
naked_string {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_NAKED_STRING;
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
$this->yypopstate();
}
@@ -276,10 +273,10 @@ whitespace {
return false;
}
naked_string {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_NAKED_STRING;
$this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
}
newline {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_NEWLINE;
$this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
$this->yypopstate();
}
@@ -289,10 +286,10 @@ newline {
%statename SECTION
dot {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_DOT;
$this->token = Smarty_Internal_Configfileparser::TPC_DOT;
}
section {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_SECTION;
$this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
$this->yypopstate();
}
@@ -301,7 +298,7 @@ section {
%statename TRIPPLE
tripple_quotes_end {
$this->token = \Smarty\Parser\ConfigfileParser::TPC_TRIPPLE_QUOTES_END;
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
$this->yypopstate();
$this->yypushstate(self::START);
}
@@ -314,7 +311,7 @@ text {
$this->compiler->trigger_config_file_error ('missing or misspelled literal closing tag');
}
$this->value = substr($this->data,$this->counter,$to-$this->counter);
$this->token = \Smarty\Parser\ConfigfileParser::TPC_TRIPPLE_TEXT;
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
}
*/
@@ -1,5 +1,5 @@
/**
* ConfigfileParser
* Smarty Internal Plugin Configfileparser
*
* This is the config file parser
*
@@ -10,22 +10,16 @@
*/
%name TPC_
%declare_class {
namespace Smarty\Parser;
use \Smarty\Lexer\ConfigfileLexer as Lexer;
use \Smarty\Compiler\Configfile as Configfile;
/**
* Smarty Internal Plugin Configfileparse
*
* This is the config file parser.
* It is generated from the ConfigfileParser.y file
* It is generated from the smarty_internal_configfileparser.y file
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
class ConfigfileParser
class Smarty_Internal_Configfileparser
}
%include_class
{
@@ -48,7 +42,7 @@ class ConfigfileParser
/**
* lexer object
*
* @var Lexer
* @var Smarty_Internal_Configfilelexer
*/
private $lex;
/**
@@ -60,7 +54,7 @@ class ConfigfileParser
/**
* compiler object
*
* @var Configfile
* @var Smarty_Internal_Config_File_Compiler
*/
public $compiler = null;
/**
@@ -92,13 +86,13 @@ class ConfigfileParser
/**
* constructor
*
* @param Lexer $lex
* @param Configfile $compiler
* @param Smarty_Internal_Configfilelexer $lex
* @param Smarty_Internal_Config_File_Compiler $compiler
*/
public function __construct(Lexer $lex, Configfile $compiler)
public function __construct(Smarty_Internal_Configfilelexer $lex, Smarty_Internal_Config_File_Compiler $compiler)
{
$this->lex = $lex;
$this->smarty = $compiler->getSmarty();
$this->smarty = $compiler->smarty;
$this->compiler = $compiler;
$this->configOverwrite = $this->smarty->config_overwrite;
$this->configReadHidden = $this->smarty->config_read_hidden;
@@ -243,8 +237,8 @@ class ConfigfileParser
%stack_overflow
{
$this->internalError = true;
$this->compiler->trigger_config_file_error('Stack overflow in configfile parser');
$this->internalError = true;
$this->compiler->trigger_config_file_error('Stack overflow in configfile parser');
}
// Complete config file
@@ -1,7 +1,4 @@
<?php
namespace Smarty\Lexer;
/*
* This file is part of Smarty.
*
@@ -12,14 +9,14 @@ namespace Smarty\Lexer;
*/
/**
* TemplateLexer
* Smarty_Internal_Templatelexer
* This is the template file lexer.
* It is generated from the TemplateLexer.plex file
* It is generated from the smarty_internal_templatelexer.plex file
*
*
* @author Uwe Tews <uwe.tews@googlemail.com>
*/
class TemplateLexer
class Smarty_Internal_Templatelexer
{
/**
* Source
@@ -70,6 +67,13 @@ class TemplateLexer
*/
public $taglineno;
/**
* php code type
*
* @var string
*/
public $phpType = '';
/**
* state number
*
@@ -87,7 +91,7 @@ class TemplateLexer
/**
* compiler object
*
* @var \Smarty\Compiler\Template
* @var Smarty_Internal_TemplateCompilerBase
*/
public $compiler = null;
@@ -222,9 +226,9 @@ class TemplateLexer
* constructor
*
* @param string $source template source
* @param \Smarty\Compiler\Template $compiler
* @param Smarty_Internal_TemplateCompilerBase $compiler
*/
public function __construct($source, \Smarty\Compiler\Template $compiler)
public function __construct($source, Smarty_Internal_TemplateCompilerBase $compiler)
{
$this->data = $source;
$this->dataLength = strlen($this->data);
@@ -233,7 +237,7 @@ class TemplateLexer
$this->counter += strlen($match[0]);
}
$this->line = 1;
$this->smarty = $compiler->getTemplate()->getSmarty();
$this->smarty = $compiler->template->smarty;
$this->compiler = $compiler;
$this->compiler->initDelimiterPreg();
$this->smarty_token_names['LDEL'] = $this->smarty->getLeftDelimiter();
@@ -330,6 +334,7 @@ class TemplateLexer
step = ~\s+step\s+~
if = ~(if|elseif|else if|while)\s+~
for = ~for\s+~
makenocache = ~make_nocache\s+~
array = ~array~
foreach = ~foreach(?![^\s])~
setfilter = ~setfilter\s+~
@@ -341,7 +346,7 @@ class TemplateLexer
/*!lex2php
%statename TEXT
emptyjava {
$this->token = \Smarty\Parser\TemplateParser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
comment {
$to = $this->dataLength;
@@ -355,14 +360,14 @@ class TemplateLexer
return false;
}
userliteral {
$this->token = \Smarty\Parser\TemplateParser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
ldel literal rdel {
$this->token = \Smarty\Parser\TemplateParser::TP_LITERALSTART;
$this->token = Smarty_Internal_Templateparser::TP_LITERALSTART;
$this->yypushstate(self::LITERAL);
}
ldel slash literal rdel {
$this->token = \Smarty\Parser\TemplateParser::TP_LITERALEND;
$this->token = Smarty_Internal_Templateparser::TP_LITERALEND;
$this->yypushstate(self::LITERAL);
}
ldel {
@@ -379,65 +384,70 @@ class TemplateLexer
$to = $match[0][1];
}
$this->value = substr($this->data,$this->counter,$to-$this->counter);
$this->token = \Smarty\Parser\TemplateParser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
*/
/*!lex2php
%statename TAG
ldel if {
$this->token = \Smarty\Parser\TemplateParser::TP_LDELIF;
$this->token = Smarty_Internal_Templateparser::TP_LDELIF;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel for {
$this->token = \Smarty\Parser\TemplateParser::TP_LDELFOR;
$this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel foreach {
$this->token = \Smarty\Parser\TemplateParser::TP_LDELFOREACH;
$this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel setfilter {
$this->token = \Smarty\Parser\TemplateParser::TP_LDELSETFILTER;
$this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel makenocache {
$this->token = Smarty_Internal_Templateparser::TP_LDELMAKENOCACHE;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel id nocacherdel {
$this->yypopstate();
$this->token = \Smarty\Parser\TemplateParser::TP_SIMPLETAG;
$this->token = Smarty_Internal_Templateparser::TP_SIMPLETAG;
$this->taglineno = $this->line;
}
ldel smartyblockchildparent rdel {
$this->yypopstate();
$this->token = \Smarty\Parser\TemplateParser::TP_SMARTYBLOCKCHILDPARENT;
$this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILDPARENT;
$this->taglineno = $this->line;
}
ldel slash id rdel {
$this->yypopstate();
$this->token = \Smarty\Parser\TemplateParser::TP_CLOSETAG;
$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\Parser\TemplateParser::TP_SIMPELOUTPUT;
$this->token = Smarty_Internal_Templateparser::TP_SIMPELOUTPUT;
$this->taglineno = $this->line;
} else {
$this->value = $this->smarty->getLeftDelimiter();
$this->token = \Smarty\Parser\TemplateParser::TP_LDEL;
$this->token = Smarty_Internal_Templateparser::TP_LDEL;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
}
ldel slash {
$this->token = \Smarty\Parser\TemplateParser::TP_LDELSLASH;
$this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
ldel {
$this->token = \Smarty\Parser\TemplateParser::TP_LDEL;
$this->token = Smarty_Internal_Templateparser::TP_LDEL;
$this->yybegin(self::TAGBODY);
$this->taglineno = $this->line;
}
@@ -445,7 +455,7 @@ class TemplateLexer
/*!lex2php
%statename TAGBODY
rdel {
$this->token = \Smarty\Parser\TemplateParser::TP_RDEL;
$this->token = Smarty_Internal_Templateparser::TP_RDEL;
$this->yypopstate();
}
ldel {
@@ -453,143 +463,143 @@ class TemplateLexer
return true;
}
double_quote {
$this->token = \Smarty\Parser\TemplateParser::TP_QUOTE;
$this->token = Smarty_Internal_Templateparser::TP_QUOTE;
$this->yypushstate(self::DOUBLEQUOTEDSTRING);
$this->compiler->enterDoubleQuote();
}
singlequotestring {
$this->token = \Smarty\Parser\TemplateParser::TP_SINGLEQUOTESTRING;
$this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING;
}
dollar id {
$this->token = \Smarty\Parser\TemplateParser::TP_DOLLARID;
$this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
}
dollar {
$this->token = \Smarty\Parser\TemplateParser::TP_DOLLAR;
$this->token = Smarty_Internal_Templateparser::TP_DOLLAR;
}
isin {
$this->token = \Smarty\Parser\TemplateParser::TP_ISIN;
$this->token = Smarty_Internal_Templateparser::TP_ISIN;
}
as {
$this->token = \Smarty\Parser\TemplateParser::TP_AS;
$this->token = Smarty_Internal_Templateparser::TP_AS;
}
to {
$this->token = \Smarty\Parser\TemplateParser::TP_TO;
$this->token = Smarty_Internal_Templateparser::TP_TO;
}
step {
$this->token = \Smarty\Parser\TemplateParser::TP_STEP;
$this->token = Smarty_Internal_Templateparser::TP_STEP;
}
instanceof {
$this->token = \Smarty\Parser\TemplateParser::TP_INSTANCEOF;
$this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF;
}
lop {
$this->token = \Smarty\Parser\TemplateParser::TP_LOGOP;
$this->token = Smarty_Internal_Templateparser::TP_LOGOP;
}
slop {
$this->token = \Smarty\Parser\TemplateParser::TP_SLOGOP;
$this->token = Smarty_Internal_Templateparser::TP_SLOGOP;
}
tlop {
$this->token = \Smarty\Parser\TemplateParser::TP_TLOGOP;
$this->token = Smarty_Internal_Templateparser::TP_TLOGOP;
}
scond {
$this->token = \Smarty\Parser\TemplateParser::TP_SINGLECOND;
$this->token = Smarty_Internal_Templateparser::TP_SINGLECOND;
}
not{
$this->token = \Smarty\Parser\TemplateParser::TP_NOT;
$this->token = Smarty_Internal_Templateparser::TP_NOT;
}
typecast {
$this->token = \Smarty\Parser\TemplateParser::TP_TYPECAST;
$this->token = Smarty_Internal_Templateparser::TP_TYPECAST;
}
openP {
$this->token = \Smarty\Parser\TemplateParser::TP_OPENP;
$this->token = Smarty_Internal_Templateparser::TP_OPENP;
}
closeP {
$this->token = \Smarty\Parser\TemplateParser::TP_CLOSEP;
$this->token = Smarty_Internal_Templateparser::TP_CLOSEP;
}
openB {
$this->token = \Smarty\Parser\TemplateParser::TP_OPENB;
$this->token = Smarty_Internal_Templateparser::TP_OPENB;
}
closeB {
$this->token = \Smarty\Parser\TemplateParser::TP_CLOSEB;
$this->token = Smarty_Internal_Templateparser::TP_CLOSEB;
}
ptr {
$this->token = \Smarty\Parser\TemplateParser::TP_PTR;
$this->token = Smarty_Internal_Templateparser::TP_PTR;
}
aptr {
$this->token = \Smarty\Parser\TemplateParser::TP_APTR;
$this->token = Smarty_Internal_Templateparser::TP_APTR;
}
equal {
$this->token = \Smarty\Parser\TemplateParser::TP_EQUAL;
$this->token = Smarty_Internal_Templateparser::TP_EQUAL;
}
incdec {
$this->token = \Smarty\Parser\TemplateParser::TP_INCDEC;
$this->token = Smarty_Internal_Templateparser::TP_INCDEC;
}
unimath {
$this->token = \Smarty\Parser\TemplateParser::TP_UNIMATH;
$this->token = Smarty_Internal_Templateparser::TP_UNIMATH;
}
math {
$this->token = \Smarty\Parser\TemplateParser::TP_MATH;
$this->token = Smarty_Internal_Templateparser::TP_MATH;
}
at {
$this->token = \Smarty\Parser\TemplateParser::TP_AT;
$this->token = Smarty_Internal_Templateparser::TP_AT;
}
array openP {
$this->token = \Smarty\Parser\TemplateParser::TP_ARRAYOPEN;
$this->token = Smarty_Internal_Templateparser::TP_ARRAYOPEN;
}
hatch {
$this->token = \Smarty\Parser\TemplateParser::TP_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->compiler->getRdelLength()) === $this->smarty->getRightDelimiter()) {
preg_match('/\s+/',$this->value,$match);
$this->value = $match[0];
$this->token = \Smarty\Parser\TemplateParser::TP_SPACE;
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
} else {
$this->token = \Smarty\Parser\TemplateParser::TP_ATTR;
$this->token = Smarty_Internal_Templateparser::TP_ATTR;
}
}
namespace {
$this->token = \Smarty\Parser\TemplateParser::TP_NAMESPACE;
$this->token = Smarty_Internal_Templateparser::TP_NAMESPACE;
}
id {
$this->token = \Smarty\Parser\TemplateParser::TP_ID;
$this->token = Smarty_Internal_Templateparser::TP_ID;
}
integer {
$this->token = \Smarty\Parser\TemplateParser::TP_INTEGER;
$this->token = Smarty_Internal_Templateparser::TP_INTEGER;
}
backtick {
$this->token = \Smarty\Parser\TemplateParser::TP_BACKTICK;
$this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
$this->yypopstate();
}
vert {
$this->token = \Smarty\Parser\TemplateParser::TP_VERT;
$this->token = Smarty_Internal_Templateparser::TP_VERT;
}
dot {
$this->token = \Smarty\Parser\TemplateParser::TP_DOT;
$this->token = Smarty_Internal_Templateparser::TP_DOT;
}
comma {
$this->token = \Smarty\Parser\TemplateParser::TP_COMMA;
$this->token = Smarty_Internal_Templateparser::TP_COMMA;
}
semicolon {
$this->token = \Smarty\Parser\TemplateParser::TP_SEMICOLON;
$this->token = Smarty_Internal_Templateparser::TP_SEMICOLON;
}
doublecolon {
$this->token = \Smarty\Parser\TemplateParser::TP_DOUBLECOLON;
$this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON;
}
colon {
$this->token = \Smarty\Parser\TemplateParser::TP_COLON;
$this->token = Smarty_Internal_Templateparser::TP_COLON;
}
qmark {
$this->token = \Smarty\Parser\TemplateParser::TP_QMARK;
$this->token = Smarty_Internal_Templateparser::TP_QMARK;
}
hex {
$this->token = \Smarty\Parser\TemplateParser::TP_HEX;
$this->token = Smarty_Internal_Templateparser::TP_HEX;
}
space {
$this->token = \Smarty\Parser\TemplateParser::TP_SPACE;
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
}
char {
$this->token = \Smarty\Parser\TemplateParser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
*/
@@ -597,14 +607,14 @@ class TemplateLexer
%statename LITERAL
ldel literal rdel {
$this->literal_cnt++;
$this->token = \Smarty\Parser\TemplateParser::TP_LITERAL;
$this->token = Smarty_Internal_Templateparser::TP_LITERAL;
}
ldel slash literal rdel {
if ($this->literal_cnt) {
$this->literal_cnt--;
$this->token = \Smarty\Parser\TemplateParser::TP_LITERAL;
$this->token = Smarty_Internal_Templateparser::TP_LITERAL;
} else {
$this->token = \Smarty\Parser\TemplateParser::TP_LITERALEND;
$this->token = Smarty_Internal_Templateparser::TP_LITERALEND;
$this->yypopstate();
}
}
@@ -620,19 +630,19 @@ class TemplateLexer
$this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
}
$this->value = substr($this->data,$this->counter,$to-$this->counter);
$this->token = \Smarty\Parser\TemplateParser::TP_LITERAL;
$this->token = Smarty_Internal_Templateparser::TP_LITERAL;
}
*/
/*!lex2php
%statename DOUBLEQUOTEDSTRING
userliteral {
$this->token = \Smarty\Parser\TemplateParser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
ldel literal rdel {
$this->token = \Smarty\Parser\TemplateParser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
ldel slash literal rdel {
$this->token = \Smarty\Parser\TemplateParser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
ldel slash {
$this->yypushstate(self::TAG);
@@ -643,33 +653,33 @@ class TemplateLexer
return true;
}
ldel {
$this->token = \Smarty\Parser\TemplateParser::TP_LDEL;
$this->token = Smarty_Internal_Templateparser::TP_LDEL;
$this->taglineno = $this->line;
$this->yypushstate(self::TAGBODY);
}
double_quote {
$this->token = \Smarty\Parser\TemplateParser::TP_QUOTE;
$this->token = Smarty_Internal_Templateparser::TP_QUOTE;
$this->yypopstate();
}
backtick dollar {
$this->token = \Smarty\Parser\TemplateParser::TP_BACKTICK;
$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\Parser\TemplateParser::TP_DOLLARID;
$this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
}
dollar {
$this->token = \Smarty\Parser\TemplateParser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
textdoublequoted {
$this->token = \Smarty\Parser\TemplateParser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
char {
$to = $this->dataLength;
$this->value = substr($this->data,$this->counter,$to-$this->counter);
$this->token = \Smarty\Parser\TemplateParser::TP_TEXT;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
*/
}
@@ -9,27 +9,15 @@
%stack_size 500
%name TP_
%declare_class {
namespace Smarty\Parser;
use \Smarty\Lexer\TemplateLexer as Lexer;
use \Smarty\ParseTree\Template as TemplateParseTree;
use \Smarty\Compiler\Template as TemplateCompiler;
use \Smarty\ParseTree\Code;
use \Smarty\ParseTree\Dq;
use \Smarty\ParseTree\DqContent;
use \Smarty\ParseTree\Tag;
/**
* Smarty Template Parser Class
*
* This is the template parser.
* It is generated from the TemplateParser.y file
* It is generated from the smarty_internal_templateparser.y file
*
* @author Uwe Tews <uwe.tews@googlemail.com>
*/
class TemplateParser
class Smarty_Internal_Templateparser
}
%include_class
{
@@ -72,21 +60,21 @@ class TemplateParser
/**
* root parse tree buffer
*
* @var TemplateParseTree
* @var Smarty_Internal_ParseTree_Template
*/
public $root_buffer;
/**
* current parse tree object
*
* @var \Smarty\ParseTree\Base
* @var Smarty_Internal_ParseTree
*/
public $current_buffer;
/**
* lexer object
*
* @var Lexer
* @var Smarty_Internal_Templatelexer
*/
public $lex;
@@ -106,21 +94,21 @@ class TemplateParser
/**
* compiler object
*
* @var TemplateCompiler
* @var Smarty_Internal_TemplateCompilerBase
*/
public $compiler = null;
/**
* smarty object
*
* @var \Smarty\Smarty
* @var Smarty
*/
public $smarty = null;
/**
* template object
*
* @var \Smarty\Template
* @var Smarty_Internal_Template
*/
public $template = null;
@@ -134,38 +122,38 @@ class TemplateParser
/**
* security object
*
* @var \Smarty\Security
* @var Smarty_Security
*/
public $security = null;
/**
* template prefix array
*
* @var \Smarty\ParseTree\Base[]
* @var \Smarty_Internal_ParseTree[]
*/
public $template_prefix = array();
/**
* template prefix array
*
* @var \Smarty\ParseTree\Base[]
* @var \Smarty_Internal_ParseTree[]
*/
public $template_postfix = array();
/**
* constructor
*
* @param Lexer $lex
* @param TemplateCompiler $compiler
* @param Smarty_Internal_Templatelexer $lex
* @param Smarty_Internal_TemplateCompilerBase $compiler
*/
public function __construct(Lexer $lex, TemplateCompiler $compiler)
public function __construct(Smarty_Internal_Templatelexer $lex, Smarty_Internal_TemplateCompilerBase $compiler)
{
$this->lex = $lex;
$this->compiler = $compiler;
$this->template = $this->compiler->getTemplate();
$this->smarty = $this->template->getSmarty();
$this->security = $this->smarty->security_policy ?? false;
$this->current_buffer = $this->root_buffer = new TemplateParseTree();
$this->template = $this->compiler->template;
$this->smarty = $this->template->smarty;
$this->security = isset($this->smarty->security_policy) ? $this->smarty->security_policy : false;
$this->current_buffer = $this->root_buffer = new Smarty_Internal_ParseTree_Template();
}
/**
@@ -175,7 +163,7 @@ class TemplateParser
*/
public function insertPhpCode($code)
{
$this->current_buffer->append_subtree($this, new Tag($this, $code));
$this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Tag($this, $code));
}
/**
@@ -197,9 +185,9 @@ class TemplateParser
*
* @param string $code
*
* @return Tag
* @return Smarty_Internal_ParseTree_Tag
*/
private function mergePrefixCode($code)
public function mergePrefixCode($code)
{
$tmp = '';
foreach ($this->compiler->prefix_code as $preCode) {
@@ -207,7 +195,7 @@ class TemplateParser
}
$this->compiler->prefix_code = array();
$tmp .= $code;
return new Tag($this, $this->compiler->processNocacheCode($tmp));
return new Smarty_Internal_ParseTree_Tag($this, $this->compiler->processNocacheCode($tmp, true));
}
}
@@ -256,7 +244,7 @@ template ::= template TEXT(B). {
$this->current_buffer->append_subtree($this, null);
}
$this->current_buffer->append_subtree($this, new \Smarty\ParseTree\Text($text, $this->strip));
$this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text($text, $this->strip));
}
// strip on
template ::= template STRIPON. {
@@ -269,7 +257,7 @@ template ::= template STRIPOFF. {
// Literal
template ::= template LITERALSTART literal_e2(B) LITERALEND. {
$this->current_buffer->append_subtree($this, new \Smarty\ParseTree\Text(B));
$this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text(B));
}
@@ -294,7 +282,7 @@ template ::= template smartytag(B). {
$this->current_buffer->append_subtree($this, $this->mergePrefixCode(B));
}
$this->compiler->has_variable_string = false;
$this->block_nesting_level = $this->compiler->getTagStackCount();
$this->block_nesting_level = count($this->compiler->_tag_stack);
}
@@ -303,12 +291,11 @@ template ::= .
smartytag(A) ::= SIMPELOUTPUT(B). {
$var = trim(substr(B, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' $');
$attributes = [];
if (preg_match('/^(.*)(\s+nocache)$/', $var, $match)) {
$attributes[] = 'nocache';
$var = $match[1];
A = $this->compiler->compileTag('private_print_expression',array('nocache'),array('value'=>$this->compiler->compileVariable('\''.$match[1].'\'')));
} else {
A = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$this->compiler->compileVariable('\''.$var.'\'')));
}
A = $this->compiler->compilePrintExpression($this->compiler->compileVariable('\''.$var.'\''), $attributes);
}
// simple tag like {name}
@@ -322,7 +309,7 @@ smartytag(A)::= SIMPLETAG(B). {
if ($this->security) {
$this->security->isTrustedConstant($tag, $this->compiler);
}
A = $this->compiler->compilePrintExpression($tag);
A = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$tag));
} else {
if (preg_match('/^(.*)(\s+nocache)$/', $tag, $match)) {
A = $this->compiler->compileTag($match[1],array('\'nocache\''));
@@ -337,10 +324,10 @@ smartytag(A) ::= SMARTYBLOCKCHILDPARENT(i). {
$j = strrpos(i,'.');
if (i[$j+1] == 'c') {
// {$smarty.block.child}
A = $this->compiler->compileChildBlock();
A = $this->compiler->compileTag('child',array(),array(i));
} else {
// {$smarty.block.parent}
A = $this->compiler->compileParentBlock();
A = $this->compiler->compileTag('parent',array(),array(i));
}
}
@@ -353,7 +340,7 @@ smartytag(A) ::= LDEL tagbody(B) RDEL. {
}
// output with optional attributes
tagbody(A) ::= outattr(B). {
A = $this->compiler->compilePrintExpression(B[0], B[1]);
A = $this->compiler->compileTag('private_print_expression',B[1],array('value'=>B[0]));
}
//
@@ -393,7 +380,7 @@ tag(res) ::= LDEL ID(i) attributes(a). {
if ($this->security) {
$this->security->isTrustedConstant(i, $this->compiler);
}
res = $this->compiler->compilePrintExpression(i, a);
res = $this->compiler->compileTag('private_print_expression',a,array('value'=>i));
} else {
res = $this->compiler->compileTag(i,a);
}
@@ -403,7 +390,7 @@ tag(res) ::= LDEL ID(i). {
if ($this->security) {
$this->security->isTrustedConstant(i, $this->compiler);
}
res = $this->compiler->compilePrintExpression(i);
res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>i));
} else {
res = $this->compiler->compileTag(i,array());
}
@@ -416,7 +403,7 @@ tag(res) ::= LDEL ID(i) modifierlist(l)attributes(a). {
if ($this->security) {
$this->security->isTrustedConstant(i, $this->compiler);
}
res = $this->compiler->compilePrintExpression(i, a, l);
res = $this->compiler->compileTag('private_print_expression',a,array('value'=>i, 'modifierlist'=>l));
} else {
res = $this->compiler->compileTag(i,a, array('modifierlist'=>l));
}
@@ -432,6 +419,11 @@ tag(res) ::= LDEL ID(i) PTR ID(me) modifierlist(l) attributes(a). {
res = $this->compiler->compileTag(i,a,array('modifierlist'=>l, 'object_method'=>me));
}
// nocache tag
tag(res) ::= LDELMAKENOCACHE DOLLARID(i). {
res = $this->compiler->compileTag('make_nocache',array(array('var'=>'\''.substr(i,1).'\'')));
}
// {if}, {elseif} and {while} tag
tag(res) ::= LDELIF(i) expr(ie). {
$tag = trim(substr(i,$this->compiler->getLdelLength()));
@@ -622,16 +614,6 @@ expr(res) ::= ternary(v). {
res = v;
}
// ++$a / --$a
expr(res) ::= INCDEC(i2) DOLLARID(i). {
res = '$_smarty_tpl->getVariable(\''. substr(i,1) .'\')->preIncDec(\'' . i2 . '\')';
}
// $a++ / $a--
expr(res) ::= DOLLARID(i) INCDEC(i2). {
res = '$_smarty_tpl->getVariable(\''. substr(i,1) .'\')->postIncDec(\'' . i2 . '\')';
}
// resources/streams
expr(res) ::= DOLLARID(i) COLON ID(i2). {
res = '$_smarty_tpl->getStreamVariable(\''.substr(i,1).'://' . i2 . '\')';
@@ -770,7 +752,7 @@ value(res) ::= varindexed(vi) DOUBLECOLON static_class_access(r). {
}
$prefixVar = $this->compiler->getNewPrefixVariable();
if (vi['var'] === '\'smarty\'') {
$this->compiler->appendPrefixCode("<?php {$prefixVar} = ". (new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,vi['smarty_internal_index']).';?>');
$this->compiler->appendPrefixCode("<?php {$prefixVar} = ". $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).';?>');
} else {
$this->compiler->appendPrefixCode("<?php {$prefixVar} = ". $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index'].';?>');
}
@@ -786,7 +768,7 @@ value(res) ::= smartytag(st). {
}
value(res) ::= value(v) modifierlist(l). {
res = $this->compiler->compileModifier(l, v);
res = $this->compiler->compileTag('private_modifier',array(),array('value'=>v,'modifierlist'=>l));
}
// name space constant
value(res) ::= NAMESPACE(c). {
@@ -833,7 +815,7 @@ variable(res) ::= DOLLARID(i). {
}
variable(res) ::= varindexed(vi). {
if (vi['var'] === '\'smarty\'') {
$smarty_var = (new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,vi['smarty_internal_index']);
$smarty_var = $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']);
res = $smarty_var;
} else {
// used for array reset,next,prev,end,current
@@ -845,7 +827,7 @@ variable(res) ::= varindexed(vi). {
// variable with property
variable(res) ::= varvar(v) AT ID(p). {
res = '$_smarty_tpl->getVariable('. v .')->'.p;
res = '$_smarty_tpl->tpl_vars['. v .']->'.p;
}
// object
@@ -918,11 +900,11 @@ indexdef(res) ::= DOT LDEL expr(e) RDEL. {
// section tag index
indexdef(res) ::= OPENB ID(i)CLOSEB. {
res = '['.(new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,'[\'section\'][\''.i.'\'][\'index\']').']';
res = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.i.'\'][\'index\']').']';
}
indexdef(res) ::= OPENB ID(i) DOT ID(i2) CLOSEB. {
res = '['.(new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,'[\'section\'][\''.i.'\'][\''.i2.'\']').']';
res = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.i.'\'][\''.i2.'\']').']';
}
indexdef(res) ::= OPENB SINGLEQUOTESTRING(s) CLOSEB. {
res = '['.s.']';
@@ -988,7 +970,7 @@ varvarele(res) ::= LDEL expr(e) RDEL. {
//
object(res) ::= varindexed(vi) objectchain(oc). {
if (vi['var'] === '\'smarty\'') {
res = (new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,vi['smarty_internal_index']).oc;
res = $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).oc;
} else {
res = $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index'].oc;
}
@@ -1043,7 +1025,7 @@ objectelement(res)::= PTR method(f). {
// function
//
function(res) ::= ns1(f) OPENP params(p) CLOSEP. {
res = $this->compiler->compileFunctionCall(f, p);
res = $this->compiler->compilePHPFunctionCall(f, p);
}
@@ -1077,7 +1059,7 @@ params(res) ::= expr(e). {
res = array(e);
}
// no parameter
// kein parameter
params(res) ::= . {
res = array();
}
@@ -1254,34 +1236,34 @@ doublequoted(res) ::= doublequoted(o1) doublequotedcontent(o2). {
}
doublequoted(res) ::= doublequotedcontent(o). {
res = new Dq($this, o);
res = new Smarty_Internal_ParseTree_Dq($this, o);
}
doublequotedcontent(res) ::= BACKTICK variable(v) BACKTICK. {
res = new Code('(string)'.v);
res = new Smarty_Internal_ParseTree_Code('(string)'.v);
}
doublequotedcontent(res) ::= BACKTICK expr(e) BACKTICK. {
res = new Code('(string)('.e.')');
res = new Smarty_Internal_ParseTree_Code('(string)('.e.')');
}
doublequotedcontent(res) ::= DOLLARID(i). {
res = new Code('(string)$_smarty_tpl->getValue(\''. substr(i,1) .'\')');
res = new Smarty_Internal_ParseTree_Code('(string)$_smarty_tpl->tpl_vars[\''. substr(i,1) .'\']->value');
}
doublequotedcontent(res) ::= LDEL variable(v) RDEL. {
res = new Code('(string)'.v);
res = new Smarty_Internal_ParseTree_Code('(string)'.v);
}
doublequotedcontent(res) ::= LDEL expr(e) RDEL. {
res = new Code('(string)('.e.')');
res = new Smarty_Internal_ParseTree_Code('(string)('.e.')');
}
doublequotedcontent(res) ::= smartytag(st). {
res = new Tag($this, st);
res = new Smarty_Internal_ParseTree_Tag($this, st);
}
doublequotedcontent(res) ::= TEXT(o). {
res = new DqContent(o);
res = new Smarty_Internal_ParseTree_DqContent(o);
}
+111
View File
@@ -0,0 +1,111 @@
<?php
/**
* Smarty Autoloader
*
* @package Smarty
*/
if (!defined('SMARTY_HELPER_FUNCTIONS_LOADED')) {
include __DIR__ . '/functions.php';
}
/**
* Smarty Autoloader
*
* @package Smarty
* @author Uwe Tews
* Usage:
* require_once '...path/Autoloader.php';
* Smarty_Autoloader::register();
* or
* include '...path/bootstrap.php';
*
* $smarty = new Smarty();
*/
class Smarty_Autoloader
{
/**
* Filepath to Smarty root
*
* @var string
*/
public static $SMARTY_DIR = null;
/**
* Filepath to Smarty internal plugins
*
* @var string
*/
public static $SMARTY_SYSPLUGINS_DIR = null;
/**
* Array with Smarty core classes and their filename
*
* @var array
*/
public static $rootClasses = array('smarty' => 'Smarty.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 : __DIR__ . DIRECTORY_SEPARATOR;
self::$SMARTY_SYSPLUGINS_DIR = defined('SMARTY_SYSPLUGINS_DIR') ? SMARTY_SYSPLUGINS_DIR :
self::$SMARTY_DIR . 'sysplugins' . DIRECTORY_SEPARATOR;
spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
}
/**
* Handles auto loading of classes.
*
* @param string $class A class name.
*/
public static function autoload($class)
{
if ($class[ 0 ] !== 'S' || strpos($class, 'Smarty') !== 0) {
return;
}
$_class = smarty_strtolower_ascii($class);
if (isset(self::$rootClasses[ $_class ])) {
$file = self::$SMARTY_DIR . self::$rootClasses[ $_class ];
if (is_file($file)) {
include $file;
}
} else {
$file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php';
if (is_file($file)) {
include $file;
}
}
return;
}
}
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
<?php
/**
* This file is part of the Smarty package.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Load and register Smarty Autoloader
*/
if (!class_exists('Smarty_Autoloader')) {
include __DIR__ . '/Autoloader.php';
}
Smarty_Autoloader::register(true);
View File
+51
View File
@@ -0,0 +1,51 @@
<?php
/**
* This file is part of the Smarty package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Registers some helper/polyfill functions.
*/
const SMARTY_HELPER_FUNCTIONS_LOADED = true;
/**
* Converts the first characters in $string to uppercase (A-Z) if it is an ASCII lowercase character (a-z).
*
* May not be required when running PHP8.2+: https://wiki.php.net/rfc/strtolower-ascii
*
* @param $string
*
* @return string
*/
function smarty_ucfirst_ascii($string): string {
return smarty_strtoupper_ascii(substr($string, 0, 1)) . substr($string, 1);
}
/**
* Converts all uppercase ASCII characters (A-Z) in $string to lowercase (a-z).
*
* May not be required when running PHP8.2+: https://wiki.php.net/rfc/strtolower-ascii
*
* @param $string
*
* @return string
*/
function smarty_strtolower_ascii($string): string {
return strtr($string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
}
/**
* Converts all lowercase ASCII characters (a-z) in $string to uppercase (A-Z).
*
* May not be required when running PHP8.2+: https://wiki.php.net/rfc/strtolower-ascii
*
* @param $string
*
* @return string
*/
function smarty_strtoupper_ascii($string): string {
return strtr($string, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
}
+121
View File
@@ -0,0 +1,121 @@
<?php
/**
* Smarty plugin to format text blocks
*
* @package Smarty
* @subpackage PluginsBlock
*/
/**
* Smarty {textformat}{/textformat} block plugin
* Type: block function
* Name: textformat
* Purpose: format text a certain way with preset styles
* or custom wrap/indent settings
* Params:
*
* - style - string (email)
* - indent - integer (0)
* - wrap - integer (80)
* - wrap_char - string ("\n")
* - indent_char - string (" ")
* - wrap_boundary - boolean (true)
*
* @link https://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>
* @throws \SmartyException
*/
function smarty_block_textformat($params, $content, Smarty_Internal_Template $template, &$repeat)
{
if (is_null($content)) {
return;
}
if (Smarty::$_MBSTRING) {
$template->_checkPlugins(
array(
array(
'function' => 'smarty_modifier_mb_wordwrap',
'file' => SMARTY_PLUGINS_DIR . 'modifier.mb_wordwrap.php'
)
)
);
}
$style = null;
$indent = 0;
$indent_first = 0;
$indent_char = ' ';
$wrap = 80;
$wrap_char = "\n";
$wrap_cut = false;
$assign = null;
foreach ($params as $_key => $_val) {
switch ($_key) {
case 'style':
case 'indent_char':
case 'wrap_char':
case 'assign':
$$_key = (string)$_val;
break;
case 'indent':
case 'indent_first':
case 'wrap':
$$_key = (int)$_val;
break;
case 'wrap_cut':
$$_key = (bool)$_val;
break;
default:
trigger_error("textformat: unknown attribute '{$_key}'");
}
}
if ($style === 'email') {
$wrap = 72;
}
// split into paragraphs
$_paragraphs = preg_split('![\r\n]{2}!', $content);
foreach ($_paragraphs as &$_paragraph) {
if (!$_paragraph) {
continue;
}
// convert mult. spaces & special chars to single space
$_paragraph =
preg_replace(
array(
'!\s+!' . Smarty::$_UTF8_MODIFIER,
'!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER
),
array(
' ',
''
),
$_paragraph
);
// indent first line
if ($indent_first > 0) {
$_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph;
}
// wordwrap sentences
if (Smarty::$_MBSTRING) {
$_paragraph = smarty_modifier_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
} else {
$_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
}
// indent lines
if ($indent > 0) {
$_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph);
}
}
$_output = implode($wrap_char . $wrap_char, $_paragraphs);
if ($assign) {
$template->assign($assign, $_output);
} else {
return $_output;
}
}
+62
View File
@@ -0,0 +1,62 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {counter} function plugin
* Type: function
* Name: counter
* Purpose: print out a counter value
*
* @author Monte Ohrt <monte at ohrt dot com>
* @link https://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)
{
static $counters = array();
$name = (isset($params[ 'name' ])) ? $params[ 'name' ] : 'default';
if (!isset($counters[ $name ])) {
$counters[ $name ] = array('start' => 1, 'skip' => 1, 'direction' => 'up', 'count' => 1);
}
$counter =& $counters[ $name ];
if (isset($params[ 'start' ])) {
$counter[ 'start' ] = $counter[ 'count' ] = (int)$params[ 'start' ];
}
if (!empty($params[ 'assign' ])) {
$counter[ 'assign' ] = $params[ 'assign' ];
}
if (isset($counter[ 'assign' ])) {
$template->assign($counter[ 'assign' ], $counter[ 'count' ]);
}
if (isset($params[ 'print' ])) {
$print = (bool)$params[ 'print' ];
} else {
$print = empty($counter[ 'assign' ]);
}
if ($print) {
$retval = $counter[ 'count' ];
} else {
$retval = null;
}
if (isset($params[ 'skip' ])) {
$counter[ 'skip' ] = $params[ 'skip' ];
}
if (isset($params[ 'direction' ])) {
$counter[ 'direction' ] = $params[ 'direction' ];
}
if ($counter[ 'direction' ] === 'down') {
$counter[ 'count' ] -= $counter[ 'skip' ];
} else {
$counter[ 'count' ] += $counter[ 'skip' ];
}
return $retval;
}
+92
View File
@@ -0,0 +1,92 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {cycle} function plugin
* Type: function
* Name: cycle
* Date: May 3, 2002
* Purpose: cycle through given values
* Params:
*
* - name - name of cycle (optional)
* - values - comma separated list of values to cycle, or an array of values to cycle
* (this can be left out for subsequent calls)
* - reset - boolean - resets given var to true
* - print - boolean - print var or not. default is true
* - advance - boolean - whether or not to advance the cycle
* - delimiter - the value delimiter, default is ","
* - assign - boolean, assigns to template var instead of printed.
*
* Examples:
*
* {cycle values="#eeeeee,#d0d0d0d"}
* {cycle name=row values="one,two,three" reset=true}
* {cycle name=row}
*
* @link https://www.smarty.net/manual/en/language.function.cycle.php {cycle}
* (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author credit to Mark Priatel <mpriatel@rogers.com>
* @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
*/
function smarty_function_cycle($params, $template)
{
static $cycle_vars;
$name = (empty($params[ 'name' ])) ? 'default' : $params[ 'name' ];
$print = (isset($params[ 'print' ])) ? (bool)$params[ 'print' ] : true;
$advance = (isset($params[ 'advance' ])) ? (bool)$params[ 'advance' ] : true;
$reset = (isset($params[ 'reset' ])) ? (bool)$params[ 'reset' ] : false;
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 ][ 'index' ] = 0;
}
$cycle_vars[ $name ][ 'values' ] = $params[ 'values' ];
}
if (isset($params[ 'delimiter' ])) {
$cycle_vars[ $name ][ 'delimiter' ] = $params[ 'delimiter' ];
} elseif (!isset($cycle_vars[ $name ][ 'delimiter' ])) {
$cycle_vars[ $name ][ 'delimiter' ] = ',';
}
if (is_array($cycle_vars[ $name ][ 'values' ])) {
$cycle_array = $cycle_vars[ $name ][ 'values' ];
} else {
$cycle_array = explode($cycle_vars[ $name ][ 'delimiter' ], $cycle_vars[ $name ][ 'values' ]);
}
if (!isset($cycle_vars[ $name ][ 'index' ]) || $reset) {
$cycle_vars[ $name ][ 'index' ] = 0;
}
if (isset($params[ 'assign' ])) {
$print = false;
$template->assign($params[ 'assign' ], $cycle_array[ $cycle_vars[ $name ][ 'index' ] ]);
}
if ($print) {
$retval = $cycle_array[ $cycle_vars[ $name ][ 'index' ] ];
} else {
$retval = null;
}
if ($advance) {
if ($cycle_vars[ $name ][ 'index' ] >= count($cycle_array) - 1) {
$cycle_vars[ $name ][ 'index' ] = 0;
} else {
$cycle_vars[ $name ][ 'index' ]++;
}
}
return $retval;
}
+204
View File
@@ -0,0 +1,204 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {fetch} plugin
* Type: function
* Name: fetch
* Purpose: fetch file, web or ftp data and display results
*
* @link https://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;
}
// strip file protocol
if (stripos($params[ 'file' ], 'file://') === 0) {
$params[ 'file' ] = substr($params[ 'file' ], 7);
}
$protocol = strpos($params[ 'file' ], '://');
if ($protocol !== false) {
$protocol = strtolower(substr($params[ 'file' ], 0, $protocol));
}
if (isset($template->smarty->security_policy)) {
if ($protocol) {
// remote resource (or php stream, …)
if (!$template->smarty->security_policy->isTrustedUri($params[ 'file' ])) {
return;
}
} else {
// local file
if (!$template->smarty->security_policy->isTrustedResourceDir($params[ 'file' ])) {
return;
}
}
}
$content = '';
if ($protocol === 'http') {
// http fetch
if ($uri_parts = parse_url($params[ 'file' ])) {
// set defaults
$host = $server_name = $uri_parts[ 'host' ];
$timeout = 30;
$accept = 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*';
$agent = 'Smarty Template Engine ' . Smarty::SMARTY_VERSION;
$referer = '';
$uri = !empty($uri_parts[ 'path' ]) ? $uri_parts[ 'path' ] : '/';
$uri .= !empty($uri_parts[ 'query' ]) ? '?' . $uri_parts[ 'query' ] : '';
$_is_proxy = false;
if (empty($uri_parts[ 'port' ])) {
$port = 80;
} else {
$port = $uri_parts[ 'port' ];
}
if (!empty($uri_parts[ 'user' ])) {
$user = $uri_parts[ 'user' ];
}
if (!empty($uri_parts[ 'pass' ])) {
$pass = $uri_parts[ 'pass' ];
}
// loop through parameters, setup headers
foreach ($params as $param_key => $param_value) {
switch ($param_key) {
case 'file':
case 'assign':
case 'assign_headers':
break;
case 'user':
if (!empty($param_value)) {
$user = $param_value;
}
break;
case 'pass':
if (!empty($param_value)) {
$pass = $param_value;
}
break;
case 'accept':
if (!empty($param_value)) {
$accept = $param_value;
}
break;
case 'header':
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;
}
}
break;
case 'proxy_host':
if (!empty($param_value)) {
$proxy_host = $param_value;
}
break;
case 'proxy_port':
if (!preg_match('!\D!', $param_value)) {
$proxy_port = (int)$param_value;
} else {
trigger_error("[plugin] invalid value for attribute '{$param_key }'", E_USER_NOTICE);
return;
}
break;
case 'agent':
if (!empty($param_value)) {
$agent = $param_value;
}
break;
case 'referer':
if (!empty($param_value)) {
$referer = $param_value;
}
break;
case 'timeout':
if (!preg_match('!\D!', $param_value)) {
$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;
}
}
if (!empty($proxy_host) && !empty($proxy_port)) {
$_is_proxy = true;
$fp = fsockopen($proxy_host, $proxy_port, $errno, $errstr, $timeout);
} else {
$fp = fsockopen($server_name, $port, $errno, $errstr, $timeout);
}
if (!$fp) {
trigger_error("[plugin] unable to fetch: $errstr ($errno)", E_USER_NOTICE);
return;
} else {
if ($_is_proxy) {
fputs($fp, 'GET ' . $params[ 'file' ] . " HTTP/1.0\r\n");
} else {
fputs($fp, "GET $uri HTTP/1.0\r\n");
}
if (!empty($host)) {
fputs($fp, "Host: $host\r\n");
}
if (!empty($accept)) {
fputs($fp, "Accept: $accept\r\n");
}
if (!empty($agent)) {
fputs($fp, "User-Agent: $agent\r\n");
}
if (!empty($referer)) {
fputs($fp, "Referer: $referer\r\n");
}
if (isset($extra_headers) && is_array($extra_headers)) {
foreach ($extra_headers as $curr_header) {
fputs($fp, $curr_header . "\r\n");
}
}
if (!empty($user) && !empty($pass)) {
fputs($fp, 'Authorization: BASIC ' . base64_encode("$user:$pass") . "\r\n");
}
fputs($fp, "\r\n");
while (!feof($fp)) {
$content .= fgets($fp, 4096);
}
fclose($fp);
$csplit = preg_split("!\r\n\r\n!", $content, 2);
$content = $csplit[ 1 ];
if (!empty($params[ 'assign_headers' ])) {
$template->assign($params[ 'assign_headers' ], preg_split("!\r\n!", $csplit[ 0 ]));
}
}
} else {
trigger_error("[plugin fetch] unable to parse URL, check syntax", E_USER_NOTICE);
return;
}
} else {
$content = @file_get_contents($params[ 'file' ]);
if ($content === false) {
throw new SmartyException("{fetch} cannot read resource '" . $params[ 'file' ] . "'");
}
}
if (!empty($params[ 'assign' ])) {
$template->assign($params[ 'assign' ], $content);
} else {
return $content;
}
}
+286
View File
@@ -0,0 +1,286 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_checkboxes} function plugin
* File: function.html_checkboxes.php
* Type: function
* Name: html_checkboxes
* Date: 24.Feb.2003
* Purpose: Prints out a list of checkbox input types
* Examples:
*
* {html_checkboxes values=$ids output=$names}
* {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
* {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
*
* Params:
*
* - name (optional) - string default "checkbox"
* - values (required) - array
* - options (optional) - associative array
* - checked (optional) - array default not set
* - separator (optional) - ie <br> or &nbsp;
* - output (optional) - the output next to each checkbox
* - assign (optional) - assign the output as an array to this variable
* - escape (optional) - escape the content (not value), defaults to true
*
* @link https://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
* (Smarty online manual)
* @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()
* @throws \SmartyException
*/
function smarty_function_html_checkboxes($params, Smarty_Internal_Template $template)
{
$template->_checkPlugins(
array(
array(
'function' => 'smarty_function_escape_special_chars',
'file' => SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'
)
)
);
$name = 'checkbox';
$values = null;
$options = null;
$selected = array();
$separator = '';
$escape = true;
$labels = true;
$label_ids = false;
$output = null;
$extra = '';
foreach ($params as $_key => $_val) {
switch ($_key) {
case 'name':
case 'separator':
$$_key = (string)$_val;
break;
case 'escape':
case 'labels':
case 'label_ids':
$$_key = (bool)$_val;
break;
case 'options':
$$_key = (array)$_val;
break;
case 'values':
case 'output':
$$_key = array_values((array)$_val);
break;
case 'checked':
case 'selected':
if (is_array($_val)) {
$selected = array();
foreach ($_val as $_sel) {
if (is_object($_sel)) {
if (method_exists($_sel, '__toString')) {
$_sel = smarty_function_escape_special_chars((string)$_sel->__toString());
} else {
trigger_error(
'html_checkboxes: selected attribute contains an object of class \'' .
get_class($_sel) . '\' without __toString() method',
E_USER_NOTICE
);
continue;
}
} else {
$_sel = smarty_function_escape_special_chars((string)$_sel);
}
$selected[ $_sel ] = true;
}
} elseif (is_object($_val)) {
if (method_exists($_val, '__toString')) {
$selected = smarty_function_escape_special_chars((string)$_val->__toString());
} else {
trigger_error(
'html_checkboxes: selected attribute is an object of class \'' . get_class($_val) .
'\' without __toString() method',
E_USER_NOTICE
);
}
} else {
$selected = smarty_function_escape_special_chars((string)$_val);
}
break;
case 'checkboxes':
trigger_error(
'html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead',
E_USER_WARNING
);
$options = (array)$_val;
break;
case 'assign':
break;
case 'strict':
break;
case 'disabled':
case 'readonly':
if (!empty($params[ 'strict' ])) {
if (!is_scalar($_val)) {
trigger_error(
"html_options: {$_key} attribute must be a scalar, only boolean true or string '{$_key}' will actually add the attribute",
E_USER_NOTICE
);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
// no break
default:
if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
} else {
trigger_error("html_checkboxes: extra attribute '{$_key}' cannot be an array", E_USER_NOTICE);
}
break;
}
}
if (!isset($options) && !isset($values)) {
return '';
} /* raise error here? */
$_html_result = array();
if (isset($options)) {
foreach ($options as $_key => $_val) {
$_html_result[] =
smarty_function_html_checkboxes_output(
$name,
$_key,
$_val,
$selected,
$extra,
$separator,
$labels,
$label_ids,
$escape
);
}
} else {
foreach ($values as $_i => $_key) {
$_val = isset($output[ $_i ]) ? $output[ $_i ] : '';
$_html_result[] =
smarty_function_html_checkboxes_output(
$name,
$_key,
$_val,
$selected,
$extra,
$separator,
$labels,
$label_ids,
$escape
);
}
}
if (!empty($params[ 'assign' ])) {
$template->assign($params[ 'assign' ], $_html_result);
} else {
return implode("\n", $_html_result);
}
}
/**
* @param $name
* @param $value
* @param $output
* @param $selected
* @param $extra
* @param $separator
* @param $labels
* @param $label_ids
* @param bool $escape
*
* @return string
*/
function smarty_function_html_checkboxes_output(
$name,
$value,
$output,
$selected,
$extra,
$separator,
$labels,
$label_ids,
$escape = true
) {
$_output = '';
if (is_object($value)) {
if (method_exists($value, '__toString')) {
$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 {
$value = (string)$value;
}
if (is_object($output)) {
if (method_exists($output, '__toString')) {
$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 {
$output = (string)$output;
}
if ($labels) {
if ($label_ids) {
$_id = smarty_function_escape_special_chars(
preg_replace(
'![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER,
'_',
$name . '_' . $value
)
);
$_output .= '<label for="' . $_id . '">';
} else {
$_output .= '<label>';
}
}
$name = smarty_function_escape_special_chars($name);
$value = smarty_function_escape_special_chars($value);
if ($escape) {
$output = smarty_function_escape_special_chars($output);
}
$_output .= '<input type="checkbox" name="' . $name . '[]" value="' . $value . '"';
if ($labels && $label_ids) {
$_output .= ' id="' . $_id . '"';
}
if (is_array($selected)) {
if (isset($selected[ $value ])) {
$_output .= ' checked="checked"';
}
} elseif ($value === $selected) {
$_output .= ' checked="checked"';
}
$_output .= $extra . ' />' . $output;
if ($labels) {
$_output .= '</label>';
}
$_output .= $separator;
return $_output;
}
+158
View File
@@ -0,0 +1,158 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_image} function plugin
* Type: function
* Name: html_image
* Date: Feb 24, 2003
* Purpose: format HTML tags for the image
* Examples: {html_image file="/images/masthead.gif"}
* Output: <img src="/images/masthead.gif" width=400 height=23>
* Params:
*
* - file - (required) - file (and path) of image
* - height - (optional) - image height (default actual height)
* - width - (optional) - image width (default actual width)
* - basedir - (optional) - base directory for absolute paths, default is environment variable DOCUMENT_ROOT
* - path_prefix - prefix for path output (optional, default empty)
*
* @link https://www.smarty.net/manual/en/language.function.html.image.php {html_image}
* (Smarty online manual)
* @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()
*/
function smarty_function_html_image($params, Smarty_Internal_Template $template)
{
$template->_checkPlugins(
array(
array(
'function' => 'smarty_function_escape_special_chars',
'file' => SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'
)
)
);
$alt = '';
$file = '';
$height = '';
$width = '';
$extra = '';
$prefix = '';
$suffix = '';
$path_prefix = '';
$basedir = isset($_SERVER[ 'DOCUMENT_ROOT' ]) ? $_SERVER[ 'DOCUMENT_ROOT' ] : '';
foreach ($params as $_key => $_val) {
switch ($_key) {
case 'file':
case 'height':
case 'width':
case 'dpi':
case 'path_prefix':
case 'basedir':
$$_key = $_val;
break;
case 'alt':
if (!is_array($_val)) {
$$_key = smarty_function_escape_special_chars($_val);
} else {
throw new SmartyException(
"html_image: extra attribute '{$_key}' cannot be an array",
E_USER_NOTICE
);
}
break;
case 'link':
case 'href':
$prefix = '<a href="' . $_val . '">';
$suffix = '</a>';
break;
default:
if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
} else {
throw new SmartyException(
"html_image: extra attribute '{$_key}' cannot be an array",
E_USER_NOTICE
);
}
break;
}
}
if (empty($file)) {
trigger_error('html_image: missing \'file\' parameter', E_USER_NOTICE);
return;
}
if ($file[ 0 ] === '/') {
$_image_path = $basedir . $file;
} else {
$_image_path = $file;
}
// strip file protocol
if (stripos($params[ 'file' ], 'file://') === 0) {
$params[ 'file' ] = substr($params[ 'file' ], 7);
}
$protocol = strpos($params[ 'file' ], '://');
if ($protocol !== false) {
$protocol = strtolower(substr($params[ 'file' ], 0, $protocol));
}
if (isset($template->smarty->security_policy)) {
if ($protocol) {
// remote resource (or php stream, …)
if (!$template->smarty->security_policy->isTrustedUri($params[ 'file' ])) {
return;
}
} else {
// local file
if (!$template->smarty->security_policy->isTrustedResourceDir($_image_path)) {
return;
}
}
}
if (!isset($params[ 'width' ]) || !isset($params[ 'height' ])) {
// FIXME: (rodneyrehm) getimagesize() loads the complete file off a remote resource, use custom [jpg,png,gif]header reader!
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;
}
}
if (!isset($params[ 'width' ])) {
$width = $_image_data[ 0 ];
}
if (!isset($params[ 'height' ])) {
$height = $_image_data[ 1 ];
}
}
if (isset($params[ 'dpi' ])) {
if (strstr($_SERVER[ 'HTTP_USER_AGENT' ], 'Mac')) {
// FIXME: (rodneyrehm) wrong dpi assumption
// don't know who thought this up… even if it was true in 1998, it's definitely wrong in 2011.
$dpi_default = 72;
} else {
$dpi_default = 96;
}
$_resize = $dpi_default / $params[ 'dpi' ];
$width = round($width * $_resize);
$height = round($height * $_resize);
}
return $prefix . '<img src="' . $path_prefix . $file . '" alt="' . $alt . '" width="' . $width . '" height="' .
$height . '"' . $extra . ' />' . $suffix;
}
+230
View File
@@ -0,0 +1,230 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_options} function plugin
* Type: function
* Name: html_options
* Purpose: Prints the list of <option> tags generated from
* the passed parameters
* Params:
*
* - name (optional) - string default "select"
* - values (required) - if no options supplied) - array
* - options (required) - if no values supplied) - associative array
* - selected (optional) - string default not set
* - output (required) - if not options supplied) - array
* - id (optional) - string default not set
* - class (optional) - string default not set
*
* @link https://www.smarty.net/manual/en/language.function.html.options.php {html_image}
* (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
*
* @return string
* @uses smarty_function_escape_special_chars()
* @throws \SmartyException
*/
function smarty_function_html_options($params, Smarty_Internal_Template $template)
{
$template->_checkPlugins(
array(
array(
'function' => 'smarty_function_escape_special_chars',
'file' => SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'
)
)
);
$name = null;
$values = null;
$options = null;
$selected = null;
$output = null;
$id = null;
$class = null;
$extra = '';
foreach ($params as $_key => $_val) {
switch ($_key) {
case 'name':
case 'class':
case 'id':
$$_key = (string)$_val;
break;
case 'options':
$options = (array)$_val;
break;
case 'values':
case 'output':
$$_key = array_values((array)$_val);
break;
case 'selected':
if (is_array($_val)) {
$selected = array();
foreach ($_val as $_sel) {
if (is_object($_sel)) {
if (method_exists($_sel, '__toString')) {
$_sel = smarty_function_escape_special_chars((string)$_sel->__toString());
} else {
trigger_error(
'html_options: selected attribute contains an object of class \'' .
get_class($_sel) . '\' without __toString() method',
E_USER_NOTICE
);
continue;
}
} else {
$_sel = smarty_function_escape_special_chars((string)$_sel);
}
$selected[ $_sel ] = true;
}
} elseif (is_object($_val)) {
if (method_exists($_val, '__toString')) {
$selected = smarty_function_escape_special_chars((string)$_val->__toString());
} else {
trigger_error(
'html_options: selected attribute is an object of class \'' . get_class($_val) .
'\' without __toString() method',
E_USER_NOTICE
);
}
} else {
$selected = smarty_function_escape_special_chars((string)$_val);
}
break;
case 'strict':
break;
case 'disabled':
case 'readonly':
if (!empty($params[ 'strict' ])) {
if (!is_scalar($_val)) {
trigger_error(
"html_options: {$_key} attribute must be a scalar, only boolean true or string '{$_key}' will actually add the attribute",
E_USER_NOTICE
);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
// no break
default:
if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
} else {
trigger_error("html_options: extra attribute '{$_key}' cannot be an array", E_USER_NOTICE);
}
break;
}
}
if (!isset($options) && !isset($values)) {
/* raise error here? */
return '';
}
$_html_result = '';
$_idx = 0;
if (isset($options)) {
foreach ($options as $_key => $_val) {
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
}
} else {
foreach ($values as $_i => $_key) {
$_val = isset($output[ $_i ]) ? $output[ $_i ] : '';
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
}
}
if (!empty($name)) {
$_html_class = !empty($class) ? ' class="' . $class . '"' : '';
$_html_id = !empty($id) ? ' id="' . $id . '"' : '';
$_html_result =
'<select name="' . $name . '"' . $_html_class . $_html_id . $extra . '>' . "\n" . $_html_result .
'</select>' . "\n";
}
return $_html_result;
}
/**
* @param $key
* @param $value
* @param $selected
* @param $id
* @param $class
* @param $idx
*
* @return string
*/
function smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, &$idx)
{
if (!is_array($value)) {
$_key = smarty_function_escape_special_chars($key);
$_html_result = '<option value="' . $_key . '"';
if (is_array($selected)) {
if (isset($selected[ $_key ])) {
$_html_result .= ' selected="selected"';
}
} elseif ($_key === $selected) {
$_html_result .= ' selected="selected"';
}
$_html_class = !empty($class) ? ' class="' . $class . ' option"' : '';
$_html_id = !empty($id) ? ' id="' . $id . '-' . $idx . '"' : '';
if (is_object($value)) {
if (method_exists($value, '__toString')) {
$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 {
$value = smarty_function_escape_special_chars((string)$value);
}
$_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
$idx++;
} else {
$_idx = 0;
$_html_result =
smarty_function_html_options_optgroup(
$key,
$value,
$selected,
!empty($id) ? ($id . '-' . $idx) : null,
$class,
$_idx
);
$idx++;
}
return $_html_result;
}
/**
* @param $key
* @param $values
* @param $selected
* @param $id
* @param $class
* @param $idx
*
* @return string
*/
function smarty_function_html_options_optgroup($key, $values, $selected, $id, $class, &$idx)
{
$optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
foreach ($values as $key => $value) {
$optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $idx);
}
$optgroup_html .= "</optgroup>\n";
return $optgroup_html;
}
+266
View File
@@ -0,0 +1,266 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_radios} function plugin
* File: function.html_radios.php
* Type: function
* Name: html_radios
* Date: 24.Feb.2003
* Purpose: Prints out a list of radio input types
* Params:
*
* - name (optional) - string default "radio"
* - values (required) - array
* - options (required) - associative array
* - checked (optional) - array default not set
* - separator (optional) - ie <br> or &nbsp;
* - output (optional) - the output next to each radio button
* - assign (optional) - assign the output as an array to this variable
* - escape (optional) - escape the content (not value), defaults to true
*
* Examples:
*
* {html_radios values=$ids output=$names}
* {html_radios values=$ids name='box' separator='<br>' output=$names}
* {html_radios values=$ids checked=$checked separator='<br>' output=$names}
*
* @link https://www.smarty.net/manual/en/language.function.html.radios.php {html_radios}
* (Smarty online manual)
* @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()
* @throws \SmartyException
*/
function smarty_function_html_radios($params, Smarty_Internal_Template $template)
{
$template->_checkPlugins(
array(
array(
'function' => 'smarty_function_escape_special_chars',
'file' => SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'
)
)
);
$name = 'radio';
$values = null;
$options = null;
$selected = null;
$separator = '';
$escape = true;
$labels = true;
$label_ids = false;
$output = null;
$extra = '';
foreach ($params as $_key => $_val) {
switch ($_key) {
case 'name':
case 'separator':
$$_key = (string)$_val;
break;
case 'checked':
case 'selected':
if (is_array($_val)) {
trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
} elseif (is_object($_val)) {
if (method_exists($_val, '__toString')) {
$selected = smarty_function_escape_special_chars((string)$_val->__toString());
} else {
trigger_error(
'html_radios: selected attribute is an object of class \'' . get_class($_val) .
'\' without __toString() method',
E_USER_NOTICE
);
}
} else {
$selected = (string)$_val;
}
break;
case 'escape':
case 'labels':
case 'label_ids':
$$_key = (bool)$_val;
break;
case 'options':
$$_key = (array)$_val;
break;
case 'values':
case 'output':
$$_key = array_values((array)$_val);
break;
case 'radios':
trigger_error(
'html_radios: the use of the "radios" attribute is deprecated, use "options" instead',
E_USER_WARNING
);
$options = (array)$_val;
break;
case 'assign':
break;
case 'strict':
break;
case 'disabled':
case 'readonly':
if (!empty($params[ 'strict' ])) {
if (!is_scalar($_val)) {
trigger_error(
"html_options: {$_key} attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute",
E_USER_NOTICE
);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
// no break
default:
if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
} else {
trigger_error("html_radios: extra attribute '{$_key}' cannot be an array", E_USER_NOTICE);
}
break;
}
}
if (!isset($options) && !isset($values)) {
/* raise error here? */
return '';
}
$_html_result = array();
if (isset($options)) {
foreach ($options as $_key => $_val) {
$_html_result[] =
smarty_function_html_radios_output(
$name,
$_key,
$_val,
$selected,
$extra,
$separator,
$labels,
$label_ids,
$escape
);
}
} else {
foreach ($values as $_i => $_key) {
$_val = isset($output[ $_i ]) ? $output[ $_i ] : '';
$_html_result[] =
smarty_function_html_radios_output(
$name,
$_key,
$_val,
$selected,
$extra,
$separator,
$labels,
$label_ids,
$escape
);
}
}
if (!empty($params[ 'assign' ])) {
$template->assign($params[ 'assign' ], $_html_result);
} else {
return implode("\n", $_html_result);
}
}
/**
* @param $name
* @param $value
* @param $output
* @param $selected
* @param $extra
* @param $separator
* @param $labels
* @param $label_ids
* @param $escape
*
* @return string
*/
function smarty_function_html_radios_output(
$name,
$value,
$output,
$selected,
$extra,
$separator,
$labels,
$label_ids,
$escape
) {
$_output = '';
if (is_object($value)) {
if (method_exists($value, '__toString')) {
$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 {
$value = (string)$value;
}
if (is_object($output)) {
if (method_exists($output, '__toString')) {
$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 {
$output = (string)$output;
}
if ($labels) {
if ($label_ids) {
$_id = smarty_function_escape_special_chars(
preg_replace(
'![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER,
'_',
$name . '_' . $value
)
);
$_output .= '<label for="' . $_id . '">';
} else {
$_output .= '<label>';
}
}
$name = smarty_function_escape_special_chars($name);
$value = smarty_function_escape_special_chars($value);
if ($escape) {
$output = smarty_function_escape_special_chars($output);
}
$_output .= '<input type="radio" name="' . $name . '" value="' . $value . '"';
if ($labels && $label_ids) {
$_output .= ' id="' . $_id . '"';
}
if ($value === $selected) {
$_output .= ' checked="checked"';
}
$_output .= $extra . ' />' . $output;
if ($labels) {
$_output .= '</label>';
}
$_output .= $separator;
return $_output;
}
+395
View File
@@ -0,0 +1,395 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_select_date} plugin
* Type: function
* Name: html_select_date
* Purpose: Prints the dropdowns for date selection.
* ChangeLog:
*
* - 1.0 initial release
* - 1.1 added support for +/- N syntax for begin
* and end year values. (Monte)
* - 1.2 added support for yyyy-mm-dd syntax for
* time value. (Jan Rosier)
* - 1.3 added support for choosing format for
* month values (Gary Loescher)
* - 1.3.1 added support for choosing format for
* day values (Marcus Bointon)
* - 1.3.2 support negative timestamps, force year
* dropdown to include given date unless explicitly set (Monte)
* - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
* of 0000-00-00 dates (cybot, boots)
* - 2.0 complete rewrite for performance,
* added attributes month_names, *_id
*
* @link https://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date}
* (Smarty online manual)
* @version 2.0
* @author Andrei Zmievski
* @author Monte Ohrt <monte at ohrt dot com>
* @author Rodney Rehm
*
* @param array $params parameters
*
* @param \Smarty_Internal_Template $template
*
* @return string
* @throws \SmartyException
*/
function smarty_function_html_select_date($params, Smarty_Internal_Template $template)
{
$template->_checkPlugins(
array(
array(
'function' => 'smarty_function_escape_special_chars',
'file' => SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'
)
)
);
// generate timestamps used for month names only
static $_month_timestamps = null;
static $_current_year = null;
if ($_month_timestamps === null) {
$_current_year = date('Y');
$_month_timestamps = array();
for ($i = 1; $i <= 12; $i++) {
$_month_timestamps[ $i ] = mktime(0, 0, 0, $i, 1, 2000);
}
}
/* Default values. */
$prefix = 'Date_';
$start_year = null;
$end_year = null;
$display_days = true;
$display_months = true;
$display_years = true;
$month_format = '%B';
/* Write months as numbers by default GL */
$month_value_format = '%m';
$day_format = '%02d';
/* Write day values using this format MB */
$day_value_format = '%d';
$year_as_text = false;
/* Display years in reverse order? Ie. 2000,1999,.... */
$reverse_years = false;
/* Should the select boxes be part of an array when returned from PHP?
e.g. setting it to "birthday", would create "birthday[Day]",
"birthday[Month]" & "birthday[Year]". Can be combined with prefix */
$field_array = null;
/* <select size>'s of the different <select> tags.
If not set, uses default dropdown. */
$day_size = null;
$month_size = null;
$year_size = null;
/* Unparsed attributes common to *ALL* the <select>/<input> tags.
An example might be in the template: all_extra ='class ="foo"'. */
$all_extra = null;
/* Separate attributes for the tags. */
$day_extra = null;
$month_extra = null;
$year_extra = null;
/* Order in which to display the fields.
"D" -> day, "M" -> month, "Y" -> year. */
$field_order = 'MDY';
/* String printed between the different fields. */
$field_separator = "\n";
$option_separator = "\n";
$time = null;
// $all_empty = null;
// $day_empty = null;
// $month_empty = null;
// $year_empty = null;
$extra_attrs = '';
$all_id = null;
$day_id = null;
$month_id = null;
$year_id = null;
foreach ($params as $_key => $_value) {
switch ($_key) {
case 'time':
$$_key = $_value; // we'll handle conversion below
break;
case 'month_names':
if (is_array($_value) && count($_value) === 12) {
$$_key = $_value;
} else {
trigger_error('html_select_date: month_names must be an array of 12 strings', E_USER_NOTICE);
}
break;
case 'prefix':
case 'field_array':
case 'start_year':
case 'end_year':
case 'day_format':
case 'day_value_format':
case 'month_format':
case 'month_value_format':
case 'day_size':
case 'month_size':
case 'year_size':
case 'all_extra':
case 'day_extra':
case 'month_extra':
case 'year_extra':
case 'field_order':
case 'field_separator':
case 'option_separator':
case 'all_empty':
case 'month_empty':
case 'day_empty':
case 'year_empty':
case 'all_id':
case 'month_id':
case 'day_id':
case 'year_id':
$$_key = (string)$_value;
break;
case 'display_days':
case 'display_months':
case 'display_years':
case 'year_as_text':
case 'reverse_years':
$$_key = (bool)$_value;
break;
default:
if (!is_array($_value)) {
$extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
} else {
trigger_error("html_select_date: extra attribute '{$_key}' cannot be an array", E_USER_NOTICE);
}
break;
}
}
// Note: date() is faster than strftime()
// Note: explode(date()) is faster than date() date() date()
if (isset($time) && is_array($time)) {
if (isset($time[$prefix . 'Year'])) {
// $_REQUEST[$field_array] given
foreach ([
'Y' => 'Year',
'm' => 'Month',
'd' => 'Day'
] as $_elementKey => $_elementName) {
$_variableName = '_' . strtolower($_elementName);
$$_variableName =
isset($time[$prefix . $_elementName]) ? $time[$prefix . $_elementName] :
date($_elementKey);
}
} elseif (isset($time[$field_array][$prefix . 'Year'])) {
// $_REQUEST given
foreach ([
'Y' => 'Year',
'm' => 'Month',
'd' => 'Day'
] as $_elementKey => $_elementName) {
$_variableName = '_' . strtolower($_elementName);
$$_variableName = isset($time[$field_array][$prefix . $_elementName]) ?
$time[$field_array][$prefix . $_elementName] : date($_elementKey);
}
} else {
// no date found, use NOW
[$_year, $_month, $_day] = explode('-', date('Y-m-d'));
}
} elseif (isset($time) && preg_match("/(\d*)-(\d*)-(\d*)/", $time, $matches)) {
$_year = $_month = $_day = null;
if ($matches[1] > '') $_year = (int) $matches[1];
if ($matches[2] > '') $_month = (int) $matches[2];
if ($matches[3] > '') $_day = (int) $matches[3];
} elseif ($time === null) {
if (array_key_exists('time', $params)) {
$_year = $_month = $_day = null;
} else {
[$_year, $_month, $_day] = explode('-', date('Y-m-d'));
}
} else {
$template->_checkPlugins(
array(
array(
'function' => 'smarty_make_timestamp',
'file' => SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'
)
)
);
$time = smarty_make_timestamp($time);
[$_year, $_month, $_day] = explode('-', date('Y-m-d', $time));
}
// make syntax "+N" or "-N" work with $start_year and $end_year
// Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr
foreach (array(
'start',
'end'
) as $key) {
$key .= '_year';
$t = $$key;
if ($t === null) {
$$key = (int)$_current_year;
} elseif ($t[ 0 ] === '+') {
$$key = (int)($_current_year + (int)trim(substr($t, 1)));
} elseif ($t[ 0 ] === '-') {
$$key = (int)($_current_year - (int)trim(substr($t, 1)));
} else {
$$key = (int)$$key;
}
}
// flip for ascending or descending
if (($start_year > $end_year && !$reverse_years) || ($start_year < $end_year && $reverse_years)) {
$t = $end_year;
$end_year = $start_year;
$start_year = $t;
}
// generate year <select> or <input>
if ($display_years) {
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($year_extra) {
$_extra .= ' ' . $year_extra;
}
if ($year_as_text) {
$_html_years =
'<input type="text" name="' . $_name . '" value="' . $_year . '" size="4" maxlength="4"' . $_extra .
$extra_attrs . ' />';
} else {
$_html_years = '<select name="' . $_name . '"';
if ($year_id !== null || $all_id !== null) {
$_html_years .= ' id="' . smarty_function_escape_special_chars(
$year_id !== null ?
($year_id ? $year_id : $_name) :
($all_id ? ($all_id . $_name) :
$_name)
) . '"';
}
if ($year_size) {
$_html_years .= ' size="' . $year_size . '"';
}
$_html_years .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($year_empty) || isset($all_empty)) {
$_html_years .= '<option value="">' . (isset($year_empty) ? $year_empty : $all_empty) . '</option>' .
$option_separator;
}
$op = $start_year > $end_year ? -1 : 1;
for ($i = $start_year; $op > 0 ? $i <= $end_year : $i >= $end_year; $i += $op) {
$_html_years .= '<option value="' . $i . '"' . ($_year == $i ? ' selected="selected"' : '') . '>' . $i .
'</option>' . $option_separator;
}
$_html_years .= '</select>';
}
}
// generate month <select> or <input>
if ($display_months) {
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($month_extra) {
$_extra .= ' ' . $month_extra;
}
$_html_months = '<select name="' . $_name . '"';
if ($month_id !== null || $all_id !== null) {
$_html_months .= ' id="' . smarty_function_escape_special_chars(
$month_id !== null ?
($month_id ? $month_id : $_name) :
($all_id ? ($all_id . $_name) :
$_name)
) . '"';
}
if ($month_size) {
$_html_months .= ' size="' . $month_size . '"';
}
$_html_months .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($month_empty) || isset($all_empty)) {
$_html_months .= '<option value="">' . (isset($month_empty) ? $month_empty : $all_empty) . '</option>' .
$option_separator;
}
for ($i = 1; $i <= 12; $i++) {
$_val = sprintf('%02d', $i);
$_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[ $i ]) :
($month_format === '%m' ? $_val : @strftime($month_format, $_month_timestamps[ $i ]));
$_value = $month_value_format === '%m' ? $_val : @strftime($month_value_format, $_month_timestamps[ $i ]);
$_html_months .= '<option value="' . $_value . '"' . ($_val == $_month ? ' selected="selected"' : '') .
'>' . $_text . '</option>' . $option_separator;
}
$_html_months .= '</select>';
}
// generate day <select> or <input>
if ($display_days) {
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($day_extra) {
$_extra .= ' ' . $day_extra;
}
$_html_days = '<select name="' . $_name . '"';
if ($day_id !== null || $all_id !== null) {
$_html_days .= ' id="' .
smarty_function_escape_special_chars(
$day_id !== null ? ($day_id ? $day_id : $_name) :
($all_id ? ($all_id . $_name) : $_name)
) . '"';
}
if ($day_size) {
$_html_days .= ' size="' . $day_size . '"';
}
$_html_days .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($day_empty) || isset($all_empty)) {
$_html_days .= '<option value="">' . (isset($day_empty) ? $day_empty : $all_empty) . '</option>' .
$option_separator;
}
for ($i = 1; $i <= 31; $i++) {
$_val = sprintf('%02d', $i);
$_text = $day_format === '%02d' ? $_val : sprintf($day_format, $i);
$_value = $day_value_format === '%02d' ? $_val : sprintf($day_value_format, $i);
$_html_days .= '<option value="' . $_value . '"' . ($_val == $_day ? ' selected="selected"' : '') . '>' .
$_text . '</option>' . $option_separator;
}
$_html_days .= '</select>';
}
// order the fields for output
$_html = '';
for ($i = 0; $i <= 2; $i++) {
switch ($field_order[ $i ]) {
case 'Y':
case 'y':
if (isset($_html_years)) {
if ($_html) {
$_html .= $field_separator;
}
$_html .= $_html_years;
}
break;
case 'm':
case 'M':
if (isset($_html_months)) {
if ($_html) {
$_html .= $field_separator;
}
$_html .= $_html_months;
}
break;
case 'd':
case 'D':
if (isset($_html_days)) {
if ($_html) {
$_html .= $field_separator;
}
$_html .= $_html_days;
}
break;
}
}
return $_html;
}
+354
View File
@@ -0,0 +1,354 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_select_time} function plugin
* Type: function
* Name: html_select_time
* Purpose: Prints the dropdowns for time selection
*
* @link https://www.smarty.net/manual/en/language.function.html.select.time.php {html_select_time}
* (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
*
* @return string
* @uses smarty_make_timestamp()
* @throws \SmartyException
*/
function smarty_function_html_select_time($params, Smarty_Internal_Template $template)
{
$template->_checkPlugins(
array(
array(
'function' => 'smarty_function_escape_special_chars',
'file' => SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'
)
)
);
$prefix = 'Time_';
$field_array = null;
$field_separator = "\n";
$option_separator = "\n";
$time = null;
$display_hours = true;
$display_minutes = true;
$display_seconds = true;
$display_meridian = true;
$hour_format = '%02d';
$hour_value_format = '%02d';
$minute_format = '%02d';
$minute_value_format = '%02d';
$second_format = '%02d';
$second_value_format = '%02d';
$hour_size = null;
$minute_size = null;
$second_size = null;
$meridian_size = null;
$all_empty = null;
$hour_empty = null;
$minute_empty = null;
$second_empty = null;
$meridian_empty = null;
$all_id = null;
$hour_id = null;
$minute_id = null;
$second_id = null;
$meridian_id = null;
$use_24_hours = true;
$minute_interval = 1;
$second_interval = 1;
$extra_attrs = '';
$all_extra = null;
$hour_extra = null;
$minute_extra = null;
$second_extra = null;
$meridian_extra = null;
foreach ($params as $_key => $_value) {
switch ($_key) {
case 'time':
if (!is_array($_value) && $_value !== null) {
$template->_checkPlugins(
array(
array(
'function' => 'smarty_make_timestamp',
'file' => SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'
)
)
);
$time = smarty_make_timestamp($_value);
}
break;
case 'prefix':
case 'field_array':
case 'field_separator':
case 'option_separator':
case 'all_extra':
case 'hour_extra':
case 'minute_extra':
case 'second_extra':
case 'meridian_extra':
case 'all_empty':
case 'hour_empty':
case 'minute_empty':
case 'second_empty':
case 'meridian_empty':
case 'all_id':
case 'hour_id':
case 'minute_id':
case 'second_id':
case 'meridian_id':
case 'hour_format':
case 'hour_value_format':
case 'minute_format':
case 'minute_value_format':
case 'second_format':
case 'second_value_format':
$$_key = (string)$_value;
break;
case 'display_hours':
case 'display_minutes':
case 'display_seconds':
case 'display_meridian':
case 'use_24_hours':
$$_key = (bool)$_value;
break;
case 'minute_interval':
case 'second_interval':
case 'hour_size':
case 'minute_size':
case 'second_size':
case 'meridian_size':
$$_key = (int)$_value;
break;
default:
if (!is_array($_value)) {
$extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
} else {
trigger_error("html_select_date: extra attribute '{$_key}' cannot be an array", E_USER_NOTICE);
}
break;
}
}
if (isset($params[ 'time' ]) && is_array($params[ 'time' ])) {
if (isset($params[ 'time' ][ $prefix . 'Hour' ])) {
// $_REQUEST[$field_array] given
foreach (array(
'H' => 'Hour',
'i' => 'Minute',
's' => 'Second'
) as $_elementKey => $_elementName) {
$_variableName = '_' . strtolower($_elementName);
$$_variableName =
isset($params[ 'time' ][ $prefix . $_elementName ]) ? $params[ 'time' ][ $prefix . $_elementName ] :
date($_elementKey);
}
$_meridian =
isset($params[ 'time' ][ $prefix . 'Meridian' ]) ? (' ' . $params[ 'time' ][ $prefix . 'Meridian' ]) :
'';
$time = strtotime($_hour . ':' . $_minute . ':' . $_second . $_meridian);
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
} elseif (isset($params[ 'time' ][ $field_array ][ $prefix . 'Hour' ])) {
// $_REQUEST given
foreach (array(
'H' => 'Hour',
'i' => 'Minute',
's' => 'Second'
) as $_elementKey => $_elementName) {
$_variableName = '_' . strtolower($_elementName);
$$_variableName = isset($params[ 'time' ][ $field_array ][ $prefix . $_elementName ]) ?
$params[ 'time' ][ $field_array ][ $prefix . $_elementName ] : date($_elementKey);
}
$_meridian = isset($params[ 'time' ][ $field_array ][ $prefix . 'Meridian' ]) ?
(' ' . $params[ 'time' ][ $field_array ][ $prefix . 'Meridian' ]) : '';
$time = strtotime($_hour . ':' . $_minute . ':' . $_second . $_meridian);
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
} else {
// no date found, use NOW
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
}
} elseif ($time === null) {
if (array_key_exists('time', $params)) {
$_hour = $_minute = $_second = $time = null;
} else {
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s'));
}
} else {
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
}
// generate hour <select>
if ($display_hours) {
$_html_hours = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Hour]') : ($prefix . 'Hour');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($hour_extra) {
$_extra .= ' ' . $hour_extra;
}
$_html_hours = '<select name="' . $_name . '"';
if ($hour_id !== null || $all_id !== null) {
$_html_hours .= ' id="' .
smarty_function_escape_special_chars(
$hour_id !== null ? ($hour_id ? $hour_id : $_name) :
($all_id ? ($all_id . $_name) : $_name)
) . '"';
}
if ($hour_size) {
$_html_hours .= ' size="' . $hour_size . '"';
}
$_html_hours .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($hour_empty) || isset($all_empty)) {
$_html_hours .= '<option value="">' . (isset($hour_empty) ? $hour_empty : $all_empty) . '</option>' .
$option_separator;
}
$start = $use_24_hours ? 0 : 1;
$end = $use_24_hours ? 23 : 12;
for ($i = $start; $i <= $end; $i++) {
$_val = sprintf('%02d', $i);
$_text = $hour_format === '%02d' ? $_val : sprintf($hour_format, $i);
$_value = $hour_value_format === '%02d' ? $_val : sprintf($hour_value_format, $i);
if (!$use_24_hours) {
$_hour12 = $_hour == 0 ? 12 : ($_hour <= 12 ? $_hour : $_hour - 12);
}
$selected = $_hour !== null ? ($use_24_hours ? $_hour == $_val : $_hour12 == $_val) : null;
$_html_hours .= '<option value="' . $_value . '"' . ($selected ? ' selected="selected"' : '') . '>' .
$_text . '</option>' . $option_separator;
}
$_html_hours .= '</select>';
}
// generate minute <select>
if ($display_minutes) {
$_html_minutes = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Minute]') : ($prefix . 'Minute');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($minute_extra) {
$_extra .= ' ' . $minute_extra;
}
$_html_minutes = '<select name="' . $_name . '"';
if ($minute_id !== null || $all_id !== null) {
$_html_minutes .= ' id="' . smarty_function_escape_special_chars(
$minute_id !== null ?
($minute_id ? $minute_id : $_name) :
($all_id ? ($all_id . $_name) :
$_name)
) . '"';
}
if ($minute_size) {
$_html_minutes .= ' size="' . $minute_size . '"';
}
$_html_minutes .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($minute_empty) || isset($all_empty)) {
$_html_minutes .= '<option value="">' . (isset($minute_empty) ? $minute_empty : $all_empty) . '</option>' .
$option_separator;
}
$selected = $_minute !== null ? ($_minute - $_minute % $minute_interval) : null;
for ($i = 0; $i <= 59; $i += $minute_interval) {
$_val = sprintf('%02d', $i);
$_text = $minute_format === '%02d' ? $_val : sprintf($minute_format, $i);
$_value = $minute_value_format === '%02d' ? $_val : sprintf($minute_value_format, $i);
$_html_minutes .= '<option value="' . $_value . '"' . ($selected === $i ? ' selected="selected"' : '') .
'>' . $_text . '</option>' . $option_separator;
}
$_html_minutes .= '</select>';
}
// generate second <select>
if ($display_seconds) {
$_html_seconds = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Second]') : ($prefix . 'Second');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($second_extra) {
$_extra .= ' ' . $second_extra;
}
$_html_seconds = '<select name="' . $_name . '"';
if ($second_id !== null || $all_id !== null) {
$_html_seconds .= ' id="' . smarty_function_escape_special_chars(
$second_id !== null ?
($second_id ? $second_id : $_name) :
($all_id ? ($all_id . $_name) :
$_name)
) . '"';
}
if ($second_size) {
$_html_seconds .= ' size="' . $second_size . '"';
}
$_html_seconds .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($second_empty) || isset($all_empty)) {
$_html_seconds .= '<option value="">' . (isset($second_empty) ? $second_empty : $all_empty) . '</option>' .
$option_separator;
}
$selected = $_second !== null ? ($_second - $_second % $second_interval) : null;
for ($i = 0; $i <= 59; $i += $second_interval) {
$_val = sprintf('%02d', $i);
$_text = $second_format === '%02d' ? $_val : sprintf($second_format, $i);
$_value = $second_value_format === '%02d' ? $_val : sprintf($second_value_format, $i);
$_html_seconds .= '<option value="' . $_value . '"' . ($selected === $i ? ' selected="selected"' : '') .
'>' . $_text . '</option>' . $option_separator;
}
$_html_seconds .= '</select>';
}
// generate meridian <select>
if ($display_meridian && !$use_24_hours) {
$_html_meridian = '';
$_extra = '';
$_name = $field_array ? ($field_array . '[' . $prefix . 'Meridian]') : ($prefix . 'Meridian');
if ($all_extra) {
$_extra .= ' ' . $all_extra;
}
if ($meridian_extra) {
$_extra .= ' ' . $meridian_extra;
}
$_html_meridian = '<select name="' . $_name . '"';
if ($meridian_id !== null || $all_id !== null) {
$_html_meridian .= ' id="' . smarty_function_escape_special_chars(
$meridian_id !== null ?
($meridian_id ? $meridian_id :
$_name) :
($all_id ? ($all_id . $_name) :
$_name)
) . '"';
}
if ($meridian_size) {
$_html_meridian .= ' size="' . $meridian_size . '"';
}
$_html_meridian .= $_extra . $extra_attrs . '>' . $option_separator;
if (isset($meridian_empty) || isset($all_empty)) {
$_html_meridian .= '<option value="">' . (isset($meridian_empty) ? $meridian_empty : $all_empty) .
'</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>';
}
$_html = '';
foreach (array(
'_html_hours',
'_html_minutes',
'_html_seconds',
'_html_meridian'
) as $k) {
if (isset($$k)) {
if ($_html) {
$_html .= $field_separator;
}
$_html .= $$k;
}
}
return $_html;
}
+164
View File
@@ -0,0 +1,164 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {html_table} function plugin
* Type: function
* Name: html_table
* Date: Feb 17, 2003
* Purpose: make an html table from an array of data
* Params:
*
* - loop - array to loop through
* - cols - number of columns, comma separated list of column names
* or array of column names
* - rows - number of rows
* - table_attr - table attributes
* - th_attr - table heading attributes (arrays are cycled)
* - tr_attr - table row attributes (arrays are cycled)
* - td_attr - table cell attributes (arrays are cycled)
* - trailpad - value to pad trailing cells with
* - caption - text for caption element
* - vdir - vertical direction (default: "down", means top-to-bottom)
* - hdir - horizontal direction (default: "right", means left-to-right)
* - inner - inner loop (default "cols": print $loop line by line,
* $loop will be printed column by column otherwise)
*
* Examples:
*
* {table loop=$data}
* {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
* {table loop=$data cols="first,second,third" tr_attr=$colors}
*
* @author Monte Ohrt <monte at ohrt dot com>
* @author credit to Messju Mohr <messju at lammfellpuschen dot de>
* @author credit to boots <boots dot smarty at yahoo dot com>
* @version 1.1
* @link https://www.smarty.net/manual/en/language.function.html.table.php {html_table}
* (Smarty online manual)
*
* @param array $params parameters
*
* @return string
*/
function smarty_function_html_table($params)
{
$table_attr = 'border="1"';
$tr_attr = '';
$th_attr = '';
$td_attr = '';
$cols = $cols_count = 3;
$rows = 3;
$trailpad = '&nbsp;';
$vdir = 'down';
$hdir = 'right';
$inner = 'cols';
$caption = '';
$loop = null;
if (!isset($params[ 'loop' ])) {
trigger_error("html_table: missing 'loop' parameter", E_USER_WARNING);
return;
}
foreach ($params as $_key => $_value) {
switch ($_key) {
case 'loop':
$$_key = (array)$_value;
break;
case 'cols':
if (is_array($_value) && !empty($_value)) {
$cols = $_value;
$cols_count = count($_value);
} elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
$cols = explode(',', $_value);
$cols_count = count($cols);
} elseif (!empty($_value)) {
$cols_count = (int)$_value;
} else {
$cols_count = $cols;
}
break;
case 'rows':
$$_key = (int)$_value;
break;
case 'table_attr':
case 'trailpad':
case 'hdir':
case 'vdir':
case 'inner':
case 'caption':
$$_key = (string)$_value;
break;
case 'tr_attr':
case 'td_attr':
case 'th_attr':
$$_key = $_value;
break;
}
}
$loop_count = count($loop);
if (empty($params[ 'rows' ])) {
/* no rows specified */
$rows = ceil($loop_count / $cols_count);
} elseif (empty($params[ 'cols' ])) {
if (!empty($params[ 'rows' ])) {
/* no cols specified, but rows */
$cols_count = ceil($loop_count / $rows);
}
}
$output = "<table $table_attr>\n";
if (!empty($caption)) {
$output .= '<caption>' . $caption . "</caption>\n";
}
if (is_array($cols)) {
$cols = ($hdir === 'right') ? $cols : array_reverse($cols);
$output .= "<thead><tr>\n";
for ($r = 0; $r < $cols_count; $r++) {
$output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
$output .= $cols[ $r ];
$output .= "</th>\n";
}
$output .= "</tr></thead>\n";
}
$output .= "<tbody>\n";
for ($r = 0; $r < $rows; $r++) {
$output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
$rx = ($vdir === 'down') ? $r * $cols_count : ($rows - 1 - $r) * $cols_count;
for ($c = 0; $c < $cols_count; $c++) {
$x = ($hdir === 'right') ? $rx + $c : $rx + $cols_count - 1 - $c;
if ($inner !== 'cols') {
/* shuffle x to loop over rows*/
$x = floor($x / $cols_count) + ($x % $cols_count) * $rows;
}
if ($x < $loop_count) {
$output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[ $x ] . "</td>\n";
} else {
$output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
}
}
$output .= "</tr>\n";
}
$output .= "</tbody>\n";
$output .= "</table>\n";
return $output;
}
/**
* @param $name
* @param $var
* @param $no
*
* @return string
*/
function smarty_function_html_table_cycle($name, $var, $no)
{
if (!is_array($var)) {
$ret = $var;
} else {
$ret = $var[ $no % count($var) ];
}
return ($ret) ? ' ' . $ret : '';
}
+142
View File
@@ -0,0 +1,142 @@
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {mailto} function plugin
* Type: function
* Name: mailto
* Date: May 21, 2002
* Purpose: automate mailto address link creation, and optionally encode them.
* Params:
*
* - address - (required) - e-mail address
* - text - (optional) - text to display, default is address
* - encode - (optional) - can be one of:
* * none : no encoding (default)
* * javascript : encode with javascript
* * javascript_charcode : encode with javascript charcode
* * hex : encode with hexadecimal (no javascript)
* - cc - (optional) - address(es) to carbon copy
* - bcc - (optional) - address(es) to blind carbon copy
* - subject - (optional) - e-mail subject
* - newsgroups - (optional) - newsgroup(s) to post to
* - followupto - (optional) - address(es) to follow up to
* - extra - (optional) - extra tags for the href link
*
* Examples:
*
* {mailto address="me@domain.com"}
* {mailto address="me@domain.com" encode="javascript"}
* {mailto address="me@domain.com" encode="hex"}
* {mailto address="me@domain.com" subject="Hello to you!"}
* {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
* {mailto address="me@domain.com" extra='class="mailto"'}
*
* @link https://www.smarty.net/manual/en/language.function.mailto.php {mailto}
* (Smarty online manual)
* @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
*
* @return string
*/
function smarty_function_mailto($params)
{
static $_allowed_encoding = [
'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' ];
}
$text = $address;
// netscape and mozilla do not decode %40 (@) in BCC field (bug?)
// so, don't encode it.
$mail_parms = [];
foreach ($params as $var => $value) {
switch ($var) {
case 'cc':
case 'bcc':
case 'followupto':
if (!empty($value)) {
$mail_parms[] = $var . '=' . str_replace(['%40', '%2C'], ['@', ','], rawurlencode($value));
}
break;
case 'subject':
case 'newsgroups':
$mail_parms[] = $var . '=' . rawurlencode($value);
break;
case 'extra':
case 'text':
$$var = $value;
// no break
default:
}
}
if ($mail_parms) {
$address .= '?' . join('&', $mail_parms);
}
$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;
}
$string = '<a href="mailto:' . htmlspecialchars($address, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, Smarty::$_CHARSET) .
'" ' . $extra . '>' . htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, Smarty::$_CHARSET) . '</a>';
if ($encode === 'javascript') {
$js_encode = '';
for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
$js_encode .= '%' . bin2hex($string[ $x ]);
}
return '<script type="text/javascript">document.write(unescape(\'' . $js_encode . '\'))</script>';
} elseif ($encode === 'javascript_charcode') {
for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
$ord[] = ord($string[ $x ]);
}
return '<script type="text/javascript">document.write(String.fromCharCode(' . implode(',', $ord) . '))</script>';
} elseif ($encode === 'hex') {
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 = '';
for ($x = 0, $_length = strlen($address); $x < $_length; $x++) {
if (preg_match('!\w!' . Smarty::$_UTF8_MODIFIER, $address[ $x ])) {
$address_encode .= '%' . bin2hex($address[ $x ]);
} else {
$address_encode .= $address[ $x ];
}
}
$text_encode = '';
for ($x = 0, $_length = strlen($text); $x < $_length; $x++) {
$text_encode .= '&#x' . bin2hex($text[ $x ]) . ';';
}
$mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>';
} else {
// no encoding
return $string;
}
}
+142
View File
@@ -0,0 +1,142 @@
<?php
/**
* Smarty plugin
* This plugin is only for Smarty2 BC
*
* @package Smarty
* @subpackage PluginsFunction
*/
/**
* Smarty {math} function plugin
* Type: function
* Name: math
* Purpose: handle math computations in template
*
* @link https://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)
{
static $_allowed_funcs =
array(
'int' => true,
'abs' => true,
'ceil' => true,
'acos' => true,
'acosh' => true,
'cos' => true,
'cosh' => true,
'deg2rad' => true,
'rad2deg' => true,
'exp' => true,
'floor' => true,
'log' => true,
'log10' => true,
'max' => true,
'min' => true,
'pi' => true,
'pow' => true,
'rand' => true,
'round' => true,
'asin' => true,
'asinh' => true,
'sin' => true,
'sinh' => true,
'sqrt' => true,
'srand' => true,
'atan' => true,
'atanh' => true,
'tan' => true,
'tanh' => true
);
// be sure equation parameter is present
if (empty($params[ 'equation' ])) {
trigger_error("math: missing equation parameter", E_USER_WARNING);
return;
}
$equation = $params[ 'equation' ];
// Remove whitespaces
$equation = preg_replace('/\s+/', '', $equation);
// Adapted from https://www.php.net/manual/en/function.eval.php#107377
$number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number
$functionsOrVars = '((?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))';
$operators = '[,+\/*\^%-]'; // Allowed math operators
$regexp = '/^(('.$number.'|'.$functionsOrVars.'|('.$functionsOrVars.'\s*\((?1)*\)|\((?1)*\)))(?:'.$operators.'(?1))?)+$/';
if (!preg_match($regexp, $equation)) {
trigger_error("math: illegal characters", E_USER_WARNING);
return;
}
// make sure parenthesis are balanced
if (substr_count($equation, '(') !== substr_count($equation, ')')) {
trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
return;
}
// disallow backticks
if (strpos($equation, '`') !== false) {
trigger_error("math: backtick character not allowed in equation", E_USER_WARNING);
return;
}
// also disallow dollar signs
if (strpos($equation, '$') !== false) {
trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING);
return;
}
foreach ($params as $key => $val) {
if ($key !== 'equation' && $key !== 'format' && $key !== 'assign') {
// 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;
}
}
}
// match all vars in equation, make sure all are passed
preg_match_all('!(?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)!', $equation, $match);
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, or missing parameter '{$curr_var}'",
E_USER_WARNING
);
return;
}
}
foreach ($params as $key => $val) {
if ($key !== 'equation' && $key !== 'format' && $key !== 'assign') {
$equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
}
}
$smarty_math_result = null;
eval("\$smarty_math_result = " . $equation . ";");
if (empty($params[ 'format' ])) {
if (empty($params[ 'assign' ])) {
return $smarty_math_result;
} else {
$template->assign($params[ 'assign' ], $smarty_math_result);
}
} else {
if (empty($params[ 'assign' ])) {
printf($params[ 'format' ], $smarty_math_result);
} else {
$template->assign($params[ 'assign' ], sprintf($params[ 'format' ], $smarty_math_result));
}
}
}

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