Skip to content

Commit

Permalink
Add assignByRef support
Browse files Browse the repository at this point in the history
  • Loading branch information
ssigwart committed Apr 6, 2024
1 parent 5400b53 commit 29a53cb
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/Data.php
Expand Up @@ -153,6 +153,62 @@ public function assign($tpl_var, $value = null, $nocache = false, $scope = null)
return $this;
}

/**
* Assigns a Smarty variable by reference
*
* @param string $tpl_var the template variable name
* @param mixed $value the value (by reference) to assign
* @param boolean $nocache if true any output of this variable will be not cached
* @param int $scope one of self::SCOPE_* constants
*
* @return Data current Data (or Smarty or \Smarty\Template) instance for
* chaining
*/
public function assignByRef($tpl_var, &$value, $nocache = false, $scope = null)
{
switch ($scope ?? $this->getDefaultScope()) {
case self::SCOPE_GLOBAL:
case self::SCOPE_SMARTY:
$this->getSmarty()->assignByRef($tpl_var, $value);
break;
case self::SCOPE_TPL_ROOT:
$ptr = $this;
while (isset($ptr->parent) && ($ptr->parent instanceof Template)) {
$ptr = $ptr->parent;
}
$ptr->assignByRef($tpl_var, $value);
break;
case self::SCOPE_ROOT:
$ptr = $this;
while (isset($ptr->parent) && !($ptr->parent instanceof Smarty)) {
$ptr = $ptr->parent;
}
$ptr->assignByRef($tpl_var, $value);
break;
case self::SCOPE_PARENT:
if ($this->parent) {
$this->parent->assignByRef($tpl_var, $value);
} else {
// assign local as fallback
$this->assignByRef($tpl_var, $value);
}
break;
case self::SCOPE_LOCAL:
default:
if (isset($this->tpl_vars[$tpl_var])) {
$this->tpl_vars[$tpl_var]->setValueByRef($value);
if ($nocache) {
$this->tpl_vars[$tpl_var]->setNocache(true);
}
} else {
$this->tpl_vars[$tpl_var] = new Variable(null, $nocache);
$this->tpl_vars[$tpl_var]->setValueByRef($value);
}
}

return $this;
}

/**
* appends values to template variables
*
Expand Down
9 changes: 9 additions & 0 deletions src/Variable.php
Expand Up @@ -31,6 +31,15 @@ public function setValue($value): void {
$this->value = $value;
}

/**
* Set value by reference
*
* @param mixed|null $value
*/
public function setValueByRef(&$value): void {
$this->value = &$value;
}

/**
* if true any output of this variable will be not cached
*
Expand Down
70 changes: 70 additions & 0 deletions tests/UnitTests/SmartyMethodsTests/AssignByRef/AssignByRefTest.php
@@ -0,0 +1,70 @@
<?php
/**
* Smarty PHPunit tests assignByRef method
*/

/**
* Class for assignByRef tests
*/
class AssignByRefTest extends PHPUnit_Smarty
{
public function setUp(): void
{
$this->setUpSmarty(__DIR__);
}

public function testInit()
{
$this->cleanDirs();
}

private $testStr = null;
/**
* Test assignByRef for nullable string property
*/
public function testAssignByRefForNullableStringProperry()
{
$this->smarty->assignByRef('myVar', $this->testStr);
$this->assertEquals(null, $this->smarty->fetch('eval:{$myVar}'));
$this->testStr = 'abc';
$this->assertEquals('abc', $this->smarty->fetch('eval:{$myVar}'));
}

/**
* Test assignByRef for string
*/
public function testAssignByRefForString()
{
$var = 'abc';
$this->smarty->assignByRef('myVar', $var);
$this->assertEquals('abc', $this->smarty->fetch('eval:{$myVar}'));
$var = 'def';
$this->assertEquals('def', $this->smarty->fetch('eval:{$myVar}'));
}

/**
* Test assignByRef for array
*/
public function testAssignByRefForArray()
{
$var = array(
'a' => 'A',
);
$this->smarty->assignByRef('myVar', $var);
$this->assertEquals('{"a":"A"}', $this->smarty->fetch('eval:{$myVar|json_encode}'));
$var['b'] = 'B';
$this->assertEquals('{"a":"A","b":"B"}', $this->smarty->fetch('eval:{$myVar|json_encode}'));
}

/**
* Test that assignByRef returns this.
*/
public function testAssignByRefReturnsThis()
{
$var = 'data';
$this->assertEquals(
'data',
$this->smarty->assignByRef('dummy', $var)->fetch('eval:{$dummy}')
);
}
}

0 comments on commit 29a53cb

Please sign in to comment.