1 <?php
2 /**
3 * Smarty Internal Plugin Data
4 *
5 * This file contains the basic classes and methodes for template and variable creation
6 *
7 * @package Smarty
8 * @subpackage Template
9 * @author Uwe Tews
10 */
12 /**
13 * Base class with template and variable methodes
14 *
15 * @package Smarty
16 * @subpackage Template
17 */
18 class Smarty_Internal_Data {
20 /**
21 * name of class used for templates
22 *
23 * @var string
24 */
25 public $template_class = 'Smarty_Internal_Template';
26 /**
27 * template variables
28 *
29 * @var array
30 */
31 public $tpl_vars = array();
32 /**
33 * parent template (if any)
34 *
35 * @var Smarty_Internal_Template
36 */
37 public $parent = null;
38 /**
39 * configuration settings
40 *
41 * @var array
42 */
43 public $config_vars = array();
45 /**
46 * assigns a Smarty variable
47 *
48 * @param array|string $tpl_var the template variable name(s)
49 * @param mixed $value the value to assign
50 * @param boolean $nocache if true any output of this variable will be not cached
51 * @param boolean $scope the scope the variable will have (local,parent or root)
52 * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
53 */
54 public function assign($tpl_var, $value = null, $nocache = false)
55 {
56 if (is_array($tpl_var)) {
57 foreach ($tpl_var as $_key => $_val) {
58 if ($_key != '') {
59 $this->tpl_vars[$_key] = new Smarty_variable($_val, $nocache);
60 }
61 }
62 } else {
63 if ($tpl_var != '') {
64 $this->tpl_vars[$tpl_var] = new Smarty_variable($value, $nocache);
65 }
66 }
68 return $this;
69 }
71 /**
72 * assigns a global Smarty variable
73 *
74 * @param string $varname the global variable name
75 * @param mixed $value the value to assign
76 * @param boolean $nocache if true any output of this variable will be not cached
77 * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
78 */
79 public function assignGlobal($varname, $value = null, $nocache = false)
80 {
81 if ($varname != '') {
82 Smarty::$global_tpl_vars[$varname] = new Smarty_variable($value, $nocache);
83 }
85 return $this;
86 }
87 /**
88 * assigns values to template variables by reference
89 *
90 * @param string $tpl_var the template variable name
91 * @param mixed $ &$value the referenced value to assign
92 * @param boolean $nocache if true any output of this variable will be not cached
93 * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
94 */
95 public function assignByRef($tpl_var, &$value, $nocache = false)
96 {
97 if ($tpl_var != '') {
98 $this->tpl_vars[$tpl_var] = new Smarty_variable(null, $nocache);
99 $this->tpl_vars[$tpl_var]->value = &$value;
100 }
102 return $this;
103 }
105 /**
106 * appends values to template variables
107 *
108 * @param array|string $tpl_var the template variable name(s)
109 * @param mixed $value the value to append
110 * @param boolean $merge flag if array elements shall be merged
111 * @param boolean $nocache if true any output of this variable will be not cached
112 * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
113 */
114 public function append($tpl_var, $value = null, $merge = false, $nocache = false)
115 {
116 if (is_array($tpl_var)) {
117 // $tpl_var is an array, ignore $value
118 foreach ($tpl_var as $_key => $_val) {
119 if ($_key != '') {
120 if (!isset($this->tpl_vars[$_key])) {
121 $tpl_var_inst = $this->getVariable($_key, null, true, false);
122 if ($tpl_var_inst instanceof Undefined_Smarty_Variable) {
123 $this->tpl_vars[$_key] = new Smarty_variable(null, $nocache);
124 } else {
125 $this->tpl_vars[$_key] = clone $tpl_var_inst;
126 }
127 }
128 if (!(is_array($this->tpl_vars[$_key]->value) || $this->tpl_vars[$_key]->value instanceof ArrayAccess)) {
129 settype($this->tpl_vars[$_key]->value, 'array');
130 }
131 if ($merge && is_array($_val)) {
132 foreach($_val as $_mkey => $_mval) {
133 $this->tpl_vars[$_key]->value[$_mkey] = $_mval;
134 }
135 } else {
136 $this->tpl_vars[$_key]->value[] = $_val;
137 }
138 }
139 }
140 } else {
141 if ($tpl_var != '' && isset($value)) {
142 if (!isset($this->tpl_vars[$tpl_var])) {
143 $tpl_var_inst = $this->getVariable($tpl_var, null, true, false);
144 if ($tpl_var_inst instanceof Undefined_Smarty_Variable) {
145 $this->tpl_vars[$tpl_var] = new Smarty_variable(null, $nocache);
146 } else {
147 $this->tpl_vars[$tpl_var] = clone $tpl_var_inst;
148 }
149 }
150 if (!(is_array($this->tpl_vars[$tpl_var]->value) || $this->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) {
151 settype($this->tpl_vars[$tpl_var]->value, 'array');
152 }
153 if ($merge && is_array($value)) {
154 foreach($value as $_mkey => $_mval) {
155 $this->tpl_vars[$tpl_var]->value[$_mkey] = $_mval;
156 }
157 } else {
158 $this->tpl_vars[$tpl_var]->value[] = $value;
159 }
160 }
161 }
163 return $this;
164 }
166 /**
167 * appends values to template variables by reference
168 *
169 * @param string $tpl_var the template variable name
170 * @param mixed &$value the referenced value to append
171 * @param boolean $merge flag if array elements shall be merged
172 * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
173 */
174 public function appendByRef($tpl_var, &$value, $merge = false)
175 {
176 if ($tpl_var != '' && isset($value)) {
177 if (!isset($this->tpl_vars[$tpl_var])) {
178 $this->tpl_vars[$tpl_var] = new Smarty_variable();
179 }
180 if (!is_array($this->tpl_vars[$tpl_var]->value)) {
181 settype($this->tpl_vars[$tpl_var]->value, 'array');
182 }
183 if ($merge && is_array($value)) {
184 foreach($value as $_key => $_val) {
185 $this->tpl_vars[$tpl_var]->value[$_key] = &$value[$_key];
186 }
187 } else {
188 $this->tpl_vars[$tpl_var]->value[] = &$value;
189 }
190 }
192 return $this;
193 }
195 /**
196 * Returns a single or all template variables
197 *
198 * @param string $varname variable name or null
199 * @param string $_ptr optional pointer to data object
200 * @param boolean $search_parents include parent templates?
201 * @return string variable value or or array of variables
202 */
203 public function getTemplateVars($varname = null, $_ptr = null, $search_parents = true)
204 {
205 if (isset($varname)) {
206 $_var = $this->getVariable($varname, $_ptr, $search_parents, false);
207 if (is_object($_var)) {
208 return $_var->value;
209 } else {
210 return null;
211 }
212 } else {
213 $_result = array();
214 if ($_ptr === null) {
215 $_ptr = $this;
216 } while ($_ptr !== null) {
217 foreach ($_ptr->tpl_vars AS $key => $var) {
218 if (!array_key_exists($key, $_result)) {
219 $_result[$key] = $var->value;
220 }
221 }
222 // not found, try at parent
223 if ($search_parents) {
224 $_ptr = $_ptr->parent;
225 } else {
226 $_ptr = null;
227 }
228 }
229 if ($search_parents && isset(Smarty::$global_tpl_vars)) {
230 foreach (Smarty::$global_tpl_vars AS $key => $var) {
231 if (!array_key_exists($key, $_result)) {
232 $_result[$key] = $var->value;
233 }
234 }
235 }
236 return $_result;
237 }
238 }
240 /**
241 * clear the given assigned template variable.
242 *
243 * @param string|array $tpl_var the template variable(s) to clear
244 * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
245 */
246 public function clearAssign($tpl_var)
247 {
248 if (is_array($tpl_var)) {
249 foreach ($tpl_var as $curr_var) {
250 unset($this->tpl_vars[$curr_var]);
251 }
252 } else {
253 unset($this->tpl_vars[$tpl_var]);
254 }
256 return $this;
257 }
259 /**
260 * clear all the assigned template variables.
261 * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
262 */
263 public function clearAllAssign()
264 {
265 $this->tpl_vars = array();
266 return $this;
267 }
269 /**
270 * load a config file, optionally load just selected sections
271 *
272 * @param string $config_file filename
273 * @param mixed $sections array of section names, single section or null
274 * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
275 */
276 public function configLoad($config_file, $sections = null)
277 {
278 // load Config class
279 $config = new Smarty_Internal_Config($config_file, $this->smarty, $this);
280 $config->loadConfigVars($sections);
281 return $this;
282 }
284 /**
285 * gets the object of a Smarty variable
286 *
287 * @param string $variable the name of the Smarty variable
288 * @param object $_ptr optional pointer to data object
289 * @param boolean $search_parents search also in parent data
290 * @return object the object of the variable
291 */
292 public function getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true)
293 {
294 if ($_ptr === null) {
295 $_ptr = $this;
296 } while ($_ptr !== null) {
297 if (isset($_ptr->tpl_vars[$variable])) {
298 // found it, return it
299 return $_ptr->tpl_vars[$variable];
300 }
301 // not found, try at parent
302 if ($search_parents) {
303 $_ptr = $_ptr->parent;
304 } else {
305 $_ptr = null;
306 }
307 }
308 if (isset(Smarty::$global_tpl_vars[$variable])) {
309 // found it, return it
310 return Smarty::$global_tpl_vars[$variable];
311 }
312 if ($this->smarty->error_unassigned && $error_enable) {
313 // force a notice
314 $x = $$variable;
315 }
316 return new Undefined_Smarty_Variable;
317 }
319 /**
320 * gets a config variable
321 *
322 * @param string $variable the name of the config variable
323 * @return mixed the value of the config variable
324 */
325 public function getConfigVariable($variable, $error_enable = true)
326 {
327 $_ptr = $this;
328 while ($_ptr !== null) {
329 if (isset($_ptr->config_vars[$variable])) {
330 // found it, return it
331 return $_ptr->config_vars[$variable];
332 }
333 // not found, try at parent
334 $_ptr = $_ptr->parent;
335 }
336 if ($this->smarty->error_unassigned && $error_enable) {
337 // force a notice
338 $x = $$variable;
339 }
340 return null;
341 }
343 /**
344 * gets a stream variable
345 *
346 * @param string $variable the stream of the variable
347 * @return mixed the value of the stream variable
348 */
349 public function getStreamVariable($variable)
350 {
351 $_result = '';
352 $fp = fopen($variable, 'r+');
353 if ($fp) {
354 while (!feof($fp) && ($current_line = fgets($fp)) !== false ) {
355 $_result .= $current_line;
356 }
357 fclose($fp);
358 return $_result;
359 }
361 if ($this->smarty->error_unassigned) {
362 throw new SmartyException('Undefined stream variable "' . $variable . '"');
363 } else {
364 return null;
365 }
366 }
368 /**
369 * Returns a single or all config variables
370 *
371 * @param string $varname variable name or null
372 * @return string variable value or or array of variables
373 */
374 public function getConfigVars($varname = null, $search_parents = true)
375 {
376 $_ptr = $this;
377 $var_array = array();
378 while ($_ptr !== null) {
379 if (isset($varname)) {
380 if (isset($_ptr->config_vars[$varname])) {
381 return $_ptr->config_vars[$varname];
382 }
383 } else {
384 $var_array = array_merge($_ptr->config_vars, $var_array);
385 }
386 // not found, try at parent
387 if ($search_parents) {
388 $_ptr = $_ptr->parent;
389 } else {
390 $_ptr = null;
391 }
392 }
393 if (isset($varname)) {
394 return '';
395 } else {
396 return $var_array;
397 }
398 }
400 /**
401 * Deassigns a single or all config variables
402 *
403 * @param string $varname variable name or null
404 * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining
405 */
406 public function clearConfig($varname = null)
407 {
408 if (isset($varname)) {
409 unset($this->config_vars[$varname]);
410 } else {
411 $this->config_vars = array();
412 }
413 return $this;
414 }
416 }
418 /**
419 * class for the Smarty data object
420 *
421 * The Smarty data object will hold Smarty variables in the current scope
422 *
423 * @package Smarty
424 * @subpackage Template
425 */
426 class Smarty_Data extends Smarty_Internal_Data {
428 /**
429 * Smarty object
430 *
431 * @var Smarty
432 */
433 public $smarty = null;
435 /**
436 * create Smarty data object
437 *
438 * @param Smarty|array $_parent parent template
439 * @param Smarty $smarty global smarty instance
440 */
441 public function __construct ($_parent = null, $smarty = null)
442 {
443 $this->smarty = $smarty;
444 if (is_object($_parent)) {
445 // when object set up back pointer
446 $this->parent = $_parent;
447 } elseif (is_array($_parent)) {
448 // set up variable values
449 foreach ($_parent as $_key => $_val) {
450 $this->tpl_vars[$_key] = new Smarty_variable($_val);
451 }
452 } elseif ($_parent != null) {
453 throw new SmartyException("Wrong type for template variables");
454 }
455 }
457 }
459 /**
460 * class for the Smarty variable object
461 *
462 * This class defines the Smarty variable object
463 *
464 * @package Smarty
465 * @subpackage Template
466 */
467 class Smarty_Variable {
469 /**
470 * template variable
471 *
472 * @var mixed
473 */
474 public $value = null;
475 /**
476 * if true any output of this variable will be not cached
477 *
478 * @var boolean
479 */
480 public $nocache = false;
481 /**
482 * the scope the variable will have (local,parent or root)
483 *
484 * @var int
485 */
486 public $scope = Smarty::SCOPE_LOCAL;
488 /**
489 * create Smarty variable object
490 *
491 * @param mixed $value the value to assign
492 * @param boolean $nocache if true any output of this variable will be not cached
493 * @param int $scope the scope the variable will have (local,parent or root)
494 */
495 public function __construct($value = null, $nocache = false, $scope = Smarty::SCOPE_LOCAL)
496 {
497 $this->value = $value;
498 $this->nocache = $nocache;
499 $this->scope = $scope;
500 }
502 /**
503 * <<magic>> String conversion
504 *
505 * @return string
506 */
507 public function __toString()
508 {
509 return (string) $this->value;
510 }
512 }
514 /**
515 * class for undefined variable object
516 *
517 * This class defines an object for undefined variable handling
518 *
519 * @package Smarty
520 * @subpackage Template
521 */
522 class Undefined_Smarty_Variable {
524 /**
525 * Returns FALSE for 'nocache' and NULL otherwise.
526 *
527 * @param string $name
528 * @return bool
529 */
530 public function __get($name)
531 {
532 if ($name == 'nocache') {
533 return false;
534 } else {
535 return null;
536 }
537 }
539 /**
540 * Always returns an empty string.
541 *
542 * @return string
543 */
544 public function __toString()
545 {
546 return "";
547 }
549 }
551 ?>