Skip to content

Commit 29a53cb

Browse files
committed
Add assignByRef support
1 parent 5400b53 commit 29a53cb

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed

src/Data.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,62 @@ public function assign($tpl_var, $value = null, $nocache = false, $scope = null)
153153
return $this;
154154
}
155155

156+
/**
157+
* Assigns a Smarty variable by reference
158+
*
159+
* @param string $tpl_var the template variable name
160+
* @param mixed $value the value (by reference) to assign
161+
* @param boolean $nocache if true any output of this variable will be not cached
162+
* @param int $scope one of self::SCOPE_* constants
163+
*
164+
* @return Data current Data (or Smarty or \Smarty\Template) instance for
165+
* chaining
166+
*/
167+
public function assignByRef($tpl_var, &$value, $nocache = false, $scope = null)
168+
{
169+
switch ($scope ?? $this->getDefaultScope()) {
170+
case self::SCOPE_GLOBAL:
171+
case self::SCOPE_SMARTY:
172+
$this->getSmarty()->assignByRef($tpl_var, $value);
173+
break;
174+
case self::SCOPE_TPL_ROOT:
175+
$ptr = $this;
176+
while (isset($ptr->parent) && ($ptr->parent instanceof Template)) {
177+
$ptr = $ptr->parent;
178+
}
179+
$ptr->assignByRef($tpl_var, $value);
180+
break;
181+
case self::SCOPE_ROOT:
182+
$ptr = $this;
183+
while (isset($ptr->parent) && !($ptr->parent instanceof Smarty)) {
184+
$ptr = $ptr->parent;
185+
}
186+
$ptr->assignByRef($tpl_var, $value);
187+
break;
188+
case self::SCOPE_PARENT:
189+
if ($this->parent) {
190+
$this->parent->assignByRef($tpl_var, $value);
191+
} else {
192+
// assign local as fallback
193+
$this->assignByRef($tpl_var, $value);
194+
}
195+
break;
196+
case self::SCOPE_LOCAL:
197+
default:
198+
if (isset($this->tpl_vars[$tpl_var])) {
199+
$this->tpl_vars[$tpl_var]->setValueByRef($value);
200+
if ($nocache) {
201+
$this->tpl_vars[$tpl_var]->setNocache(true);
202+
}
203+
} else {
204+
$this->tpl_vars[$tpl_var] = new Variable(null, $nocache);
205+
$this->tpl_vars[$tpl_var]->setValueByRef($value);
206+
}
207+
}
208+
209+
return $this;
210+
}
211+
156212
/**
157213
* appends values to template variables
158214
*

src/Variable.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ public function setValue($value): void {
3131
$this->value = $value;
3232
}
3333

34+
/**
35+
* Set value by reference
36+
*
37+
* @param mixed|null $value
38+
*/
39+
public function setValueByRef(&$value): void {
40+
$this->value = &$value;
41+
}
42+
3443
/**
3544
* if true any output of this variable will be not cached
3645
*
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
/**
3+
* Smarty PHPunit tests assignByRef method
4+
*/
5+
6+
/**
7+
* Class for assignByRef tests
8+
*/
9+
class AssignByRefTest extends PHPUnit_Smarty
10+
{
11+
public function setUp(): void
12+
{
13+
$this->setUpSmarty(__DIR__);
14+
}
15+
16+
public function testInit()
17+
{
18+
$this->cleanDirs();
19+
}
20+
21+
private $testStr = null;
22+
/**
23+
* Test assignByRef for nullable string property
24+
*/
25+
public function testAssignByRefForNullableStringProperry()
26+
{
27+
$this->smarty->assignByRef('myVar', $this->testStr);
28+
$this->assertEquals(null, $this->smarty->fetch('eval:{$myVar}'));
29+
$this->testStr = 'abc';
30+
$this->assertEquals('abc', $this->smarty->fetch('eval:{$myVar}'));
31+
}
32+
33+
/**
34+
* Test assignByRef for string
35+
*/
36+
public function testAssignByRefForString()
37+
{
38+
$var = 'abc';
39+
$this->smarty->assignByRef('myVar', $var);
40+
$this->assertEquals('abc', $this->smarty->fetch('eval:{$myVar}'));
41+
$var = 'def';
42+
$this->assertEquals('def', $this->smarty->fetch('eval:{$myVar}'));
43+
}
44+
45+
/**
46+
* Test assignByRef for array
47+
*/
48+
public function testAssignByRefForArray()
49+
{
50+
$var = array(
51+
'a' => 'A',
52+
);
53+
$this->smarty->assignByRef('myVar', $var);
54+
$this->assertEquals('{"a":"A"}', $this->smarty->fetch('eval:{$myVar|json_encode}'));
55+
$var['b'] = 'B';
56+
$this->assertEquals('{"a":"A","b":"B"}', $this->smarty->fetch('eval:{$myVar|json_encode}'));
57+
}
58+
59+
/**
60+
* Test that assignByRef returns this.
61+
*/
62+
public function testAssignByRefReturnsThis()
63+
{
64+
$var = 'data';
65+
$this->assertEquals(
66+
'data',
67+
$this->smarty->assignByRef('dummy', $var)->fetch('eval:{$dummy}')
68+
);
69+
}
70+
}

0 commit comments

Comments
 (0)