mirror of
https://github.com/smarty-php/smarty.git
synced 2026-08-06 13:34:11 +02:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5de6092a56 | |||
| 32c8339492 | |||
| 2042979701 | |||
| d0270fb8ea | |||
| 39db8ce64f | |||
| 11cc46c942 | |||
| d974bde2c4 | |||
| 3293a873bd | |||
| 8d53d3cbf2 | |||
| 47c4864dd1 | |||
| f411247aa1 | |||
| 9a8702d937 | |||
| 5ee4363000 |
@@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [5.1.0] - 2024-04-22
|
||||
- Prevent deprecation notices during compilation in PHP8.3 [#996](https://github.com/smarty-php/smarty/issues/996)
|
||||
- Fix that getTemplateVars would return an array of objects instead of the assigned variables values [#994](https://github.com/smarty-php/smarty/issues/994)
|
||||
- Fix Smarty::assign() not returning $this when called with an array as first parameter [#972](https://github.com/smarty-php/smarty/pull/972)
|
||||
- Documented support for `{if $element is in $array}` syntax [#937](https://github.com/smarty-php/smarty/issues/937)
|
||||
- Added support for `{if $element is not in $array}` syntax [#937](https://github.com/smarty-php/smarty/issues/937)
|
||||
- Using stream variables in templates now throws a deprecation notice [#933](https://github.com/smarty-php/smarty/pull/933)
|
||||
- Internal compiler classes always return a string (the internal has_code flag has been removed for simplicity) [#918](https://github.com/smarty-php/smarty/pull/918)
|
||||
- Fix invalid classnames in Runtime code for foreach [#1000](https://github.com/smarty-php/smarty/issues/1000)
|
||||
|
||||
|
||||
## [5.0.1] - 2024-03-27
|
||||
- Fix error in Smarty\Smarty::compileAllTemplates() by including missing FilesystemIterator class [#966](https://github.com/smarty-php/smarty/issues/966)
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
- Added a PSR-4 loading script to allow Smarty to be used without Composer [#1017](https://github.com/smarty-php/smarty/pull/1017)
|
||||
@@ -1 +0,0 @@
|
||||
- Internal compiler classes always return a string (the internal has_code flag has been removed for simplicity) [#918](https://github.com/smarty-php/smarty/pull/918)
|
||||
@@ -1 +0,0 @@
|
||||
- Using stream variables in templates now throws a deprecation notice [#933](https://github.com/smarty-php/smarty/pull/933)
|
||||
@@ -1,2 +0,0 @@
|
||||
- Documented support for `{if $element is in $array}` syntax [#937](https://github.com/smarty-php/smarty/issues/937)
|
||||
- Added support for `{if $element is not in $array}` syntax [#937](https://github.com/smarty-php/smarty/issues/937)
|
||||
@@ -1 +0,0 @@
|
||||
- Fix Smarty::assign() not returning $this when called with an array as first parameter [#972](https://github.com/smarty-php/smarty/pull/972)
|
||||
@@ -9,7 +9,6 @@
|
||||
|----------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| file | Yes | The name of the config file to include |
|
||||
| section | No | The name of the section to load |
|
||||
| scope | no | How the scope of the loaded variables are treated, which must be one of local, parent or global. local means variables are loaded into the local template context. parent means variables are loaded into both the local context and the parent template that called it. global means variables are available to all templates. |
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -25,9 +25,17 @@ Here's how you create an instance of Smarty in your PHP scripts:
|
||||
```php
|
||||
<?php
|
||||
|
||||
// Instantiated via composer
|
||||
require 'vendor/autoload.php';
|
||||
use Smarty\Smarty;
|
||||
$smarty = new Smarty();
|
||||
|
||||
// or ...
|
||||
|
||||
// Instantiated directly
|
||||
require("/path/to/smarty/libs/Smarty.class.php");
|
||||
use Smarty\Smarty;
|
||||
$smarty = new Smarty();
|
||||
```
|
||||
|
||||
Now that the library files are in place, it's time to set up the Smarty
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// This is a stub PSR-4 loading script that gets all the pieces of //
|
||||
// Smarty 5.x loaded without requiring the use of composer. It's //
|
||||
// not really a 'class' file, but the name is used so we're //
|
||||
// backwards compatible with previous versions of Smarty. //
|
||||
// //
|
||||
// Example: //
|
||||
// require_once("/path/to/smarty/libs/Smarty.class.php"); //
|
||||
// //
|
||||
// $smarty = new Smarty\Smarty; //
|
||||
// $smarty->testInstall(); //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
define('__SMARTY_DIR', __DIR__ . '/../src/');
|
||||
|
||||
// Global function declarations
|
||||
require_once(__SMARTY_DIR . "/functions.php");
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
// Class prefix
|
||||
$prefix = 'Smarty\\';
|
||||
|
||||
// Does the class use the namespace prefix?
|
||||
$len = strlen($prefix);
|
||||
if (strncmp($prefix, $class, $len) !== 0) {
|
||||
// If not, move to the next registered autoloader
|
||||
return;
|
||||
}
|
||||
|
||||
// Hack off the prefix part
|
||||
$relative_class = substr($class, $len);
|
||||
|
||||
// Build a path to the include file
|
||||
$file = __SMARTY_DIR . str_replace('\\', '/', $relative_class) . '.php';
|
||||
|
||||
// If the file exists, require it
|
||||
if (file_exists($file)) {
|
||||
require_once($file);
|
||||
}
|
||||
});
|
||||
@@ -43,7 +43,7 @@ class ConfigLoad extends Base {
|
||||
* @var array
|
||||
* @see BasePlugin
|
||||
*/
|
||||
protected $optional_attributes = ['section', 'scope'];
|
||||
protected $optional_attributes = ['section'];
|
||||
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
@@ -51,7 +51,7 @@ class ConfigLoad extends Base {
|
||||
* @var array
|
||||
* @see BasePlugin
|
||||
*/
|
||||
protected $option_flags = ['nocache', 'noscope'];
|
||||
protected $option_flags = [];
|
||||
|
||||
/**
|
||||
* Compiles code for the {config_load} tag
|
||||
@@ -66,9 +66,7 @@ class ConfigLoad extends Base {
|
||||
{
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
if ($_attr['nocache'] === true) {
|
||||
$compiler->trigger_template_error('nocache option not allowed', null, true);
|
||||
}
|
||||
|
||||
// save possible attributes
|
||||
$conf_file = $_attr['file'];
|
||||
$section = $_attr['section'] ?? 'null';
|
||||
|
||||
@@ -680,7 +680,8 @@ class Template extends BaseCompiler {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function appendCode($left, $right) {
|
||||
public function appendCode(string $left, string $right): string
|
||||
{
|
||||
if (preg_match('/\s*\?>\s?$/D', $left) && preg_match('/^<\?php\s+/', $right)) {
|
||||
$left = preg_replace('/\s*\?>\s?$/D', "\n", $left);
|
||||
$left .= preg_replace('/^<\?php\s+/', '', $right);
|
||||
@@ -1056,7 +1057,7 @@ class Template extends BaseCompiler {
|
||||
$prefixArray = array_merge($this->prefix_code, array_pop($this->prefixCodeStack));
|
||||
$this->prefixCodeStack[] = [];
|
||||
foreach ($prefixArray as $c) {
|
||||
$code = $this->appendCode($code, $c);
|
||||
$code = $this->appendCode($code, (string) $c);
|
||||
}
|
||||
$this->prefix_code = [];
|
||||
return $code;
|
||||
|
||||
+4
-1
@@ -224,7 +224,10 @@ class Data
|
||||
return $this->getValue($varName, $searchParents);
|
||||
}
|
||||
|
||||
return array_merge($this->parent && $searchParents ? $this->parent->getTemplateVars() : [], $this->tpl_vars);
|
||||
return array_merge(
|
||||
$this->parent && $searchParents ? $this->parent->getTemplateVars() : [],
|
||||
array_map(function(Variable $var) { return $var->getValue(); }, $this->tpl_vars)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,18 +47,18 @@ class Dq extends Base
|
||||
if ($subtree instanceof Code) {
|
||||
$this->subtrees[ $last_subtree ]->data =
|
||||
$parser->compiler->appendCode(
|
||||
$this->subtrees[ $last_subtree ]->data,
|
||||
(string) $this->subtrees[ $last_subtree ]->data,
|
||||
'<?php echo ' . $subtree->data . ';?>'
|
||||
);
|
||||
} elseif ($subtree instanceof DqContent) {
|
||||
$this->subtrees[ $last_subtree ]->data =
|
||||
$parser->compiler->appendCode(
|
||||
$this->subtrees[ $last_subtree ]->data,
|
||||
(string) $this->subtrees[ $last_subtree ]->data,
|
||||
'<?php echo "' . $subtree->data . '";?>'
|
||||
);
|
||||
} else {
|
||||
$this->subtrees[ $last_subtree ]->data =
|
||||
$parser->compiler->appendCode($this->subtrees[ $last_subtree ]->data, $subtree->data);
|
||||
$parser->compiler->appendCode((string) $this->subtrees[ $last_subtree ]->data, (string) $subtree->data);
|
||||
}
|
||||
} else {
|
||||
$this->subtrees[] = $subtree;
|
||||
|
||||
@@ -62,9 +62,9 @@ class Tag extends Base
|
||||
public function assign_to_var(\Smarty\Parser\TemplateParser $parser)
|
||||
{
|
||||
$var = $parser->compiler->getNewPrefixVariable();
|
||||
$tmp = $parser->compiler->appendCode('<?php ob_start();?>', $this->data);
|
||||
$tmp = $parser->compiler->appendCode('<?php ob_start();?>', (string) $this->data);
|
||||
$tmp = $parser->compiler->appendCode($tmp, "<?php {$var}=ob_get_clean();?>");
|
||||
$parser->compiler->appendPrefixCode((string) $tmp);
|
||||
$parser->compiler->appendPrefixCode($tmp);
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ class Template extends Base
|
||||
break;
|
||||
case 'tag':
|
||||
foreach ($chunk['subtrees'] as $subtree) {
|
||||
$text = $parser->compiler->appendCode($text, $subtree->to_smarty_php($parser));
|
||||
$text = $parser->compiler->appendCode($text, (string) $subtree->to_smarty_php($parser));
|
||||
}
|
||||
$code .= $text;
|
||||
break;
|
||||
|
||||
@@ -2536,7 +2536,7 @@ public static $yy_action = array(
|
||||
// line 806 "src/Parser/TemplateParser.y"
|
||||
public function yy_r101(){
|
||||
$prefixVar = $this->compiler->getNewPrefixVariable();
|
||||
$tmp = $this->compiler->appendCode('<?php ob_start();?>', $this->yystack[$this->yyidx + 0]->minor);
|
||||
$tmp = $this->compiler->appendCode('<?php ob_start();?>', (string) $this->yystack[$this->yyidx + 0]->minor);
|
||||
$this->compiler->appendPrefixCode($this->compiler->appendCode($tmp, "<?php {$prefixVar} = ob_get_clean();?>"));
|
||||
$this->_retvalue = $prefixVar;
|
||||
}
|
||||
|
||||
@@ -805,7 +805,7 @@ value(res) ::= varindexed(vi) DOUBLECOLON static_class_access(r). {
|
||||
// Smarty tag
|
||||
value(res) ::= smartytag(st). {
|
||||
$prefixVar = $this->compiler->getNewPrefixVariable();
|
||||
$tmp = $this->compiler->appendCode('<?php ob_start();?>', st);
|
||||
$tmp = $this->compiler->appendCode('<?php ob_start();?>', (string) st);
|
||||
$this->compiler->appendPrefixCode($this->compiler->appendCode($tmp, "<?php {$prefixVar} = ob_get_clean();?>"));
|
||||
res = $prefixVar;
|
||||
}
|
||||
|
||||
@@ -116,22 +116,20 @@ class ForeachRuntime {
|
||||
*
|
||||
* @return int the count for arrays and objects that implement countable, 1 for other objects that don't, and 0
|
||||
* for empty elements
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function count($value) {
|
||||
if ($value instanceof IteratorAggregate) {
|
||||
public function count($value): int
|
||||
{
|
||||
if ($value instanceof \IteratorAggregate) {
|
||||
// Note: getIterator() returns a Traversable, not an Iterator
|
||||
// thus rewind() and valid() methods may not be present
|
||||
return iterator_count($value->getIterator());
|
||||
} elseif ($value instanceof Iterator) {
|
||||
return $value instanceof Generator ? 1 : iterator_count($value);
|
||||
} elseif ($value instanceof Countable) {
|
||||
} elseif ($value instanceof \Iterator) {
|
||||
return $value instanceof \Generator ? 1 : iterator_count($value);
|
||||
} elseif ($value instanceof \Countable) {
|
||||
return count($value);
|
||||
} elseif ($value instanceof PDOStatement) {
|
||||
return $value->rowCount();
|
||||
} elseif ($value instanceof Traversable) {
|
||||
return iterator_count($value);
|
||||
}
|
||||
return count((array)$value);
|
||||
return count((array) $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ class Smarty extends \Smarty\TemplateBase {
|
||||
/**
|
||||
* smarty version
|
||||
*/
|
||||
const SMARTY_VERSION = '5.0.1';
|
||||
const SMARTY_VERSION = '5.1.0';
|
||||
|
||||
/**
|
||||
* define caching modes
|
||||
|
||||
@@ -1,112 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty PHPunit tests getTemplateVars method
|
||||
*
|
||||
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
/**
|
||||
* class for getTemplateVars method test
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
class GetTemplateVarsTest extends PHPUnit_Smarty
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->setUpSmarty(__DIR__);
|
||||
}
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->setUpSmarty(__DIR__);
|
||||
}
|
||||
|
||||
public function testInit()
|
||||
{
|
||||
$this->cleanDirs();
|
||||
}
|
||||
/**
|
||||
* test root getTemplateVars single value
|
||||
*/
|
||||
public function testGetSingleTemplateVarScopeRoot()
|
||||
{
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$this->smarty->assign('blar', 'buh');
|
||||
$this->assertEquals("bar", $this->smarty->getTemplateVars('foo'));
|
||||
}
|
||||
|
||||
public function testInit()
|
||||
{
|
||||
$this->cleanDirs();
|
||||
}
|
||||
/**
|
||||
* test root getTemplateVars single value
|
||||
*/
|
||||
public function testGetSingleTemplateVarScopeRoot()
|
||||
{
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$this->smarty->assign('blar', 'buh');
|
||||
$this->assertEquals("bar", $this->smarty->getTemplateVars('foo'));
|
||||
}
|
||||
/**
|
||||
* test root getTemplateVars all values
|
||||
*/
|
||||
public function testGetAllTemplateVarsScopeRoot()
|
||||
{
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$this->smarty->assign('blar', 'buh');
|
||||
$vars = $this->smarty->getTemplateVars();
|
||||
$this->assertTrue(is_array($vars));
|
||||
$this->assertEquals("bar", $vars['foo']);
|
||||
$this->assertEquals("buh", $vars['blar']);
|
||||
}
|
||||
|
||||
/**
|
||||
* test root getTemplateVars all values
|
||||
*/
|
||||
public function testGetAllTemplateVarsScopeRoot()
|
||||
{
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$this->smarty->assign('blar', 'buh');
|
||||
$vars = $this->smarty->getTemplateVars();
|
||||
$this->assertTrue(is_array($vars));
|
||||
$this->assertEquals("bar", $vars['foo']);
|
||||
$this->assertEquals("buh", $vars['blar']);
|
||||
}
|
||||
/**
|
||||
* test single variable with data object chain
|
||||
*/
|
||||
public function testGetSingleTemplateVarScopeAll()
|
||||
{
|
||||
$data1 = $this->smarty->createData($this->smarty);
|
||||
$data2 = $this->smarty->createData($data1);
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$this->smarty->assign('blar', 'buh');
|
||||
$this->assertEquals("bar", $data2->getTemplateVars('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* test single variable with data object chain
|
||||
*/
|
||||
public function testGetSingleTemplateVarScopeAll()
|
||||
{
|
||||
$data1 = $this->smarty->createData($this->smarty);
|
||||
$data2 = $this->smarty->createData($data1);
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$this->smarty->assign('blar', 'buh');
|
||||
$this->assertEquals("bar", $data2->getTemplateVars('foo'));
|
||||
}
|
||||
/**
|
||||
* test get all variables with data object chain
|
||||
*/
|
||||
public function testGetAllTemplateVarsScopeAll()
|
||||
{
|
||||
$data1 = $this->smarty->createData($this->smarty);
|
||||
$data2 = $this->smarty->createData($data1);
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$data1->assign('blar', 'buh');
|
||||
$data2->assign('foo2', 'bar2');
|
||||
$vars = $data2->getTemplateVars(null);
|
||||
$this->assertTrue(is_array($vars));
|
||||
$this->assertEquals("bar", $vars['foo']);
|
||||
$this->assertEquals("bar2", $vars['foo2']);
|
||||
$this->assertEquals("buh", $vars['blar']);
|
||||
}
|
||||
|
||||
/**
|
||||
* test get all variables with data object chain
|
||||
*/
|
||||
public function testGetAllTemplateVarsScopeAll()
|
||||
{
|
||||
$data1 = $this->smarty->createData($this->smarty);
|
||||
$data2 = $this->smarty->createData($data1);
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$data1->assign('blar', 'buh');
|
||||
$data2->assign('foo2', 'bar2');
|
||||
$vars = $data2->getTemplateVars(null);
|
||||
$this->assertTrue(is_array($vars));
|
||||
$this->assertEquals("bar", $vars['foo']);
|
||||
$this->assertEquals("bar2", $vars['foo2']);
|
||||
$this->assertEquals("buh", $vars['blar']);
|
||||
}
|
||||
/**
|
||||
* test get all variables with data object chain search parents disabled
|
||||
*/
|
||||
public function testGetAllTemplateVarsScopeAllNoParents()
|
||||
{
|
||||
$data1 = $this->smarty->createData($this->smarty);
|
||||
$data2 = $this->smarty->createData($data1);
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$data1->assign('blar', 'buh');
|
||||
$data2->assign('foo2', 'bar2');
|
||||
$vars = $data2->getTemplateVars(null, false);
|
||||
$this->assertTrue(is_array($vars));
|
||||
$this->assertFalse(isset($vars['foo']));
|
||||
$this->assertEquals("bar2", $vars['foo2']);
|
||||
$this->assertFalse(isset($vars['blar']));
|
||||
}
|
||||
|
||||
/**
|
||||
* test get all variables with data object chain search parents disabled
|
||||
*/
|
||||
public function testGetAllTemplateVarsScopeAllNoParents()
|
||||
{
|
||||
$data1 = $this->smarty->createData($this->smarty);
|
||||
$data2 = $this->smarty->createData($data1);
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$data1->assign('blar', 'buh');
|
||||
$data2->assign('foo2', 'bar2');
|
||||
$vars = $data2->getTemplateVars(null, false);
|
||||
$this->assertTrue(is_array($vars));
|
||||
$this->assertFalse(isset($vars['foo']));
|
||||
$this->assertEquals("bar2", $vars['foo2']);
|
||||
$this->assertFalse(isset($vars['blar']));
|
||||
}
|
||||
/**
|
||||
* test get single variables with data object chain search parents disabled
|
||||
*/
|
||||
public function testGetSingleTemplateVarsScopeAllNoParents()
|
||||
{
|
||||
error_reporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
|
||||
$data1 = $this->smarty->createData($this->smarty);
|
||||
$data2 = $this->smarty->createData($data1);
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$data1->assign('blar', 'buh');
|
||||
$data2->assign('foo2', 'bar2');
|
||||
$this->assertEquals("", $data2->getTemplateVars('foo', false));
|
||||
$this->assertEquals("bar2", $data2->getTemplateVars('foo2', false));
|
||||
$this->assertEquals("", $data2->getTemplateVars('blar', false));
|
||||
}
|
||||
|
||||
/**
|
||||
* test that variable assigned by global assign in template is included in getTemplateVars
|
||||
*/
|
||||
public function testAssignedInTemplate()
|
||||
{
|
||||
$this->smarty->fetch('string:{assign var="b" value="x" scope="global"}');
|
||||
$this->assertEquals('x', $this->smarty->getTemplateVars('b'));
|
||||
}
|
||||
|
||||
/**
|
||||
* test that getTemplateVars returns simple array of values
|
||||
*/
|
||||
public function testSimpleCallReturnsArrayWithAllValues()
|
||||
{
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$this->smarty->assign('i', 3);
|
||||
|
||||
$vars = $this->smarty->getTemplateVars();
|
||||
|
||||
$this->assertArrayHasKey('foo', $vars);
|
||||
$this->assertArrayHasKey('i', $vars);
|
||||
$this->assertEquals('bar', $vars['foo']);
|
||||
$this->assertEquals(3,$vars['i']);
|
||||
}
|
||||
|
||||
/**
|
||||
* test get single variables with data object chain search parents disabled
|
||||
*/
|
||||
public function testGetSingleTemplateVarsScopeAllNoParents()
|
||||
{
|
||||
error_reporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
|
||||
$data1 = $this->smarty->createData($this->smarty);
|
||||
$data2 = $this->smarty->createData($data1);
|
||||
$this->smarty->assign('foo', 'bar');
|
||||
$data1->assign('blar', 'buh');
|
||||
$data2->assign('foo2', 'bar2');
|
||||
$this->assertEquals("", $data2->getTemplateVars('foo', false));
|
||||
$this->assertEquals("bar2", $data2->getTemplateVars('foo2', false));
|
||||
$this->assertEquals("", $data2->getTemplateVars('blar', false));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user