Issues (1369)

classes/template.php (17 issues)

1
<?php
2
/**
3
*
4
* @package phpBB3
5
* @version $Id$
6
* @copyright (c) 2005 phpBB Group, sections (c) 2001 ispi of Lincoln Inc
7
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
8
*
9
* Modified by Gorlum to work within http://supernova.ws
10
*
11
*/
12
13
/**
14
* @ignore
15
*/
16
if (!defined('INSIDE'))
17
{
18
  exit;
19
}
20
21
/**
22
* Base Template class.
23
* @package phpBB3
24
*/
25
class template
26
{
27
  /** variable that holds all the data we'll be substituting into
28
  * the compiled templates. Takes form:
29
  * --> $this->_tpldata[block][iteration#][child][iteration#][child2][iteration#][variablename] == value
30
  * if it's a root-level variable, it'll be like this:
31
  * --> $this->_tpldata[.][0][varname] == value
32
  */
33
  var $_tpldata = array('.' => array(0 => array()));
34
  var $_rootref;
35
//  var $_block_counter = array();
36
  var $_block_value = array();
37
38
  // Root dir and hash of filenames for each template handle.
39
  var $root = '';
40
  var $cachepath = '';
41
  var $files = array();
42
  var $filename = array();
43
  var $files_inherit = array();
44
  var $files_template = array();
45
  var $inherit_root = '';
46
  var $orig_tpl_storedb;
47
  var $orig_tpl_inherits_id;
48
49
  // this will hash handle names to the compiled/uncompiled code for that handle.
50
  var $compiled_code = array();
51
52
  /**
53
   * Is template already parsed with SN code?
54
   *
55
   * @var bool $parsed
56
   */
57
  var $parsed = false;
58
59
  /**
60
   * @var template_compile|null $compiler
61
   */
62
  var $compiler = null;
63
64
  /**
65
   * Physical root for template search
66
   *
67
   * @var string $rootPhysical
68
   */
69
  public $rootPhysical = '';
70
71
  /**
72
   * template constructor.
73
   *
74
   * @param string $rootPhysical - physical location of game root
75
   */
76
  public function __construct($rootPhysical = SN_ROOT_PHYSICAL) {
77
    $this->rootPhysical = $rootPhysical;
78
    $this->compiler = new template_compile($this);
79
  }
80
81
  /**
82
  * Set template location
83
  * @access public
84
  */
85
  function set_template()
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
86
  {
87
    global $user;
88
89
    if (file_exists($this->rootPhysical. 'styles/' . $user->theme['template_path'] . '/template'))
90
    {
91
      $this->root = $this->rootPhysical . 'styles/' . $user->theme['template_path'] . '/template';
92
      $this->cachepath = $this->rootPhysical . 'cache/tpl_' . str_replace('_', '-', $user->theme['template_path']) . '_';
93
94
      if ($this->orig_tpl_storedb === null)
95
      {
96
        $this->orig_tpl_storedb = $user->theme['template_storedb'];
97
      }
98
99
      if ($this->orig_tpl_inherits_id === null)
100
      {
101
        $this->orig_tpl_inherits_id = $user->theme['template_inherits_id'];
102
      }
103
104
      $user->theme['template_storedb'] = $this->orig_tpl_storedb;
105
      $user->theme['template_inherits_id'] = $this->orig_tpl_inherits_id;
106
107
      if ($user->theme['template_inherits_id'])
108
      {
109
        $this->inherit_root = $this->rootPhysical . 'styles/' . $user->theme['template_inherit_path'] . '/template';
110
      }
111
    }
112
    else
113
    {
114
      trigger_error('Template path could not be found: styles/' . $user->theme['template_path'] . '/template', E_USER_ERROR);
115
    }
116
117
    $this->_rootref = &$this->_tpldata['.'][0];
118
119
    return true;
120
  }
121
122
  /**
123
  * Set custom template location (able to use directory outside of phpBB)
124
  * @access public
125
  */
126
  function set_custom_template($template_path, $template_name, $fallback_template_path = false)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
127
  {
128
    global $user;
129
130
    // Make sure $template_path has no ending slash
131
    if (substr($template_path, -1) == '/')
132
    {
133
      $template_path = substr($template_path, 0, -1);
134
    }
135
136
    $this->root = $template_path;
137
    $this->cachepath = $this->rootPhysical . 'cache/ctpl_' . str_replace('_', '-', $template_name) . '_';
138
139
    if ($fallback_template_path !== false)
140
    {
141
      if (substr($fallback_template_path, -1) == '/')
142
      {
143
        $fallback_template_path = substr($fallback_template_path, 0, -1);
144
      }
145
146
      $this->inherit_root = $fallback_template_path;
147
      $this->orig_tpl_inherits_id = true;
148
    }
149
    else
150
    {
151
      $this->orig_tpl_inherits_id = false;
152
    }
153
154
    // the database does not store the path or name of a custom template
155
    // so there is no way we can properly store custom templates there
156
    $this->orig_tpl_storedb = false;
157
158
    $this->_rootref = &$this->_tpldata['.'][0];
159
160
    return true;
161
  }
162
163
  /**
164
  * Sets the template filenames for handles. $filename_array
165
  * should be a hash of handle => filename pairs.
166
  * @access public
167
  */
168
  function set_filenames($filename_array)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
169
  {
170
    if (!is_array($filename_array))
171
    {
172
      return false;
173
    }
174
    foreach ($filename_array as $handle => $filename)
175
    {
176
      if (empty($filename))
177
      {
178
        trigger_error("template->set_filenames: Empty filename specified for $handle", E_USER_ERROR);
179
      }
180
181
      $this->filename[$handle] = $filename;
182
      $this->files[$handle] = $this->root . '/' . $filename;
183
184
      if ($this->inherit_root)
185
      {
186
        $this->files_inherit[$handle] = $this->inherit_root . '/' . $filename;
187
      }
188
    }
189
190
    return true;
191
  }
192
193
  /**
194
  * Destroy template data set
195
  * @access public
196
  */
197
  function destroy()
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
198
  {
199
    $this->_tpldata = array('.' => array(0 => array()));
200
    $this->_rootref = &$this->_tpldata['.'][0];
201
  }
202
203
  /**
204
  * Reset/empty complete block
205
  * @access public
206
  */
207
  function destroy_block_vars($blockname)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
208
  {
209
    if (strpos($blockname, '.') !== false)
210
    {
211
      // Nested block.
212
      $blocks = explode('.', $blockname);
213
      $blockcount = sizeof($blocks) - 1;
214
215
      $str = &$this->_tpldata;
216
      for ($i = 0; $i < $blockcount; $i++)
217
      {
218
        $str = &$str[$blocks[$i]];
219
        $str = &$str[sizeof($str) - 1];
220
      }
221
222
      unset($str[$blocks[$blockcount]]);
223
    }
224
    else
225
    {
226
      // Top-level block.
227
      unset($this->_tpldata[$blockname]);
228
    }
229
230
    return true;
231
  }
232
233
  /**
234
  * Display handle
235
  * @access public
236
  */
237
  function display($handle, $include_once = true)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
238
  {
239
    if (defined('IN_ERROR_HANDLER'))
240
    {
241
      $is_enotice = error_reporting();
242
      if ((E_NOTICE & $is_enotice) == E_NOTICE)
243
      {
244
        error_reporting(error_reporting() ^ E_NOTICE);
245
      }
246
    }
247
248
    if ($filename = $this->_tpl_load($handle))
249
    {
250
      ($include_once) ? include_once($filename) : include($filename);
251
    }
252
    else
253
    {
254
      $this->evaluate($this->compiled_code[$handle]);
255
    }
256
257
    return true;
258
  }
259
260
  /**
261
  * Display the handle and assign the output to a template variable or return the compiled result.
262
  * @access public
263
  */
264
  function assign_display($handle, $template_var = '', $return_content = true, $include_once = false)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
265
  {
266
    ob_start();
267
    $this->display($handle, $include_once);
268
    $contents = ob_get_clean();
269
270
    if ($return_content)
271
    {
272
      return $contents;
273
    }
274
275
    $this->assign_var($template_var, $contents);
276
277
    return true;
278
  }
279
280
  /**
281
  * Load a compiled template if possible, if not, recompile it
282
  * @access private
283
  */
284
  function _tpl_load(&$handle)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
285
  {
286
    global $user, $config;
287
288
    if (!isset($this->filename[$handle]))
289
    {
290
      trigger_error("template->_tpl_load(): No file specified for handle $handle", E_USER_ERROR);
291
    }
292
293
    // reload these settings to have the values they had when this object was initialised
294
    // using set_template or set_custom_template, they might otherwise have been overwritten
295
    // by other template class instances in between.
296
    //$user->theme['template_storedb'] = $this->orig_tpl_storedb;
297
    //$user->theme['template_inherits_id'] = $this->orig_tpl_inherits_id;
298
299
    $filename = $this->cachepath . str_replace('/', '.', $this->filename[$handle]) . DOT_PHP_EX;
300
    //$this->files_template[$handle] = (isset($user->theme['template_id'])) ? $user->theme['template_id'] : 0;
301
302
    $recompile = false;
303
    if (!file_exists($filename) || @filesize($filename) === 0)
304
    {
305
      $recompile = true;
306
    }
307
    else if ($config->load_tplcompile)
308
    {
309
      // No way around it: we need to check inheritance here
310
      if ($user->theme['template_inherits_id'] && !file_exists($this->files[$handle]))
311
      {
312
        $this->files[$handle] = $this->files_inherit[$handle];
313
        $this->files_template[$handle] = $user->theme['template_inherits_id'];
314
      }
315
      $recompile = (@filemtime($filename) < filemtime($this->files[$handle])) ? true : false;
316
    }
317
318
    // Recompile page if the original template is newer, otherwise load the compiled version
319
    if (!$recompile)
320
    {
321
      return $filename;
322
    }
323
324
    global $db;
325
326
    // Inheritance - we point to another template file for this one. Equality is also used for store_db
327
    if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'] && !file_exists($this->files[$handle]))
328
    {
329
      $this->files[$handle] = $this->files_inherit[$handle];
330
      $this->files_template[$handle] = $user->theme['template_inherits_id'];
331
    }
332
333
    $compile = $this->compiler;
334
335
    // If we don't have a file assigned to this handle, die.
336
    if (!isset($this->files[$handle]))
337
    {
338
      trigger_error("template->_tpl_load(): No file specified for handle $handle", E_USER_ERROR);
339
    }
340
341
    // Just compile if no user object is present (happens within the installer)
342
    if (!$user)
343
    {
344
      $compile->_tpl_load_file($handle);
0 ignored issues
show
The method _tpl_load_file() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

344
      $compile->/** @scrutinizer ignore-call */ 
345
                _tpl_load_file($handle);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
345
      return false;
346
    }
347
348
    if (isset($user->theme['template_storedb']) && $user->theme['template_storedb'])
349
    {
350
      $rows = array();
351
      $ids = array();
352
      // Inheritance
353
      if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'])
354
      {
355
        $ids[] = $user->theme['template_inherits_id'];
356
      }
357
      $ids[] = $user->theme['template_id'];
358
359
      foreach ($ids as $id)
360
      {
361
        $sql = 'SELECT *
362
        FROM ' . STYLES_TEMPLATE_DATA_TABLE . '
0 ignored issues
show
The constant STYLES_TEMPLATE_DATA_TABLE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
363
        WHERE template_id = ' . $id . "
364
          AND (template_filename = '" . $db->sql_escape($this->filename[$handle]) . "'
365
            OR template_included " . $db->sql_like_expression($db->any_char . $this->filename[$handle] . ':' . $db->any_char) . ')';
366
367
        $result = $db->sql_query($sql);
368
        while ($row = $db->sql_fetchrow($result))
369
        {
370
          $rows[$row['template_filename']] = $row;
371
        }
372
        $db->sql_freeresult($result);
373
      }
374
375
      if (sizeof($rows))
376
      {
377
        foreach ($rows as $row)
378
        {
379
          $file = $this->root . '/' . $row['template_filename'];
380
          $force_reload = false;
381
          if ($row['template_id'] != $user->theme['template_id'])
382
          {
383
            // make sure that we are not overlooking a file not in the db yet
384
            if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'] && !file_exists($file))
385
            {
386
              $file = $this->inherit_root . '/' . $row['template_filename'];
387
              $this->files[$row['template_filename']] = $file;
388
              $this->files_inherit[$row['template_filename']] = $file;
389
              $this->files_template[$row['template_filename']] = $user->theme['template_inherits_id'];
390
            }
391
            else if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'])
392
            {
393
              // Ok, we have a situation. There is a file in the subtemplate, but nothing in the DB. We have to fix that.
394
              $force_reload = true;
395
              $this->files_template[$row['template_filename']] = $user->theme['template_inherits_id'];
396
            }
397
          }
398
          else
399
          {
400
            $this->files_template[$row['template_filename']] = $user->theme['template_id'];
401
          }
402
403
          if ($force_reload || $row['template_mtime'] < filemtime($file))
404
          {
405
            if ($row['template_filename'] == $this->filename[$handle])
406
            {
407
              $compile->_tpl_load_file($handle, true);
408
            }
409
            else
410
            {
411
              $this->files[$row['template_filename']] = $file;
412
              $this->filename[$row['template_filename']] = $row['template_filename'];
413
              $compile->_tpl_load_file($row['template_filename'], true);
414
              unset($this->compiled_code[$row['template_filename']]);
415
              unset($this->files[$row['template_filename']]);
416
              unset($this->filename[$row['template_filename']]);
417
            }
418
          }
419
420
          if ($row['template_filename'] == $this->filename[$handle])
421
          {
422
            $this->compiled_code[$handle] = $compile->compile(trim($row['template_data']));
423
            $compile->compile_write($handle, $this->compiled_code[$handle]);
424
          }
425
          else
426
          {
427
            // Only bother compiling if it doesn't already exist
428
            if (!file_exists($this->cachepath . str_replace('/', '.', $row['template_filename']) . DOT_PHP_EX))
429
            {
430
              $this->filename[$row['template_filename']] = $row['template_filename'];
431
              $compile->compile_write($row['template_filename'], $compile->compile(trim($row['template_data'])));
432
              unset($this->filename[$row['template_filename']]);
433
            }
434
          }
435
        }
436
      }
437
      else
438
      {
439
        $file = $this->root . '/' . $row['template_filename'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $row seems to be defined by a foreach iteration on line 359. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
440
441
        if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id'] && !file_exists($file))
442
        {
443
          $file = $this->inherit_root . '/' . $row['template_filename'];
444
          $this->files[$row['template_filename']] = $file;
445
          $this->files_inherit[$row['template_filename']] = $file;
446
          $this->files_template[$row['template_filename']] = $user->theme['template_inherits_id'];
447
        }
448
        // Try to load from filesystem and instruct to insert into the styles table...
449
        $compile->_tpl_load_file($handle, true);
450
        return false;
451
      }
452
453
      return false;
454
    }
455
456
    $compile->_tpl_load_file($handle);
457
    return false;
458
  }
459
460
  /**
461
  * Assign key variable pairs from an array
462
  * @access public
463
  */
464
  function assign_vars($vararray)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
465
  {
466
    foreach ($vararray as $key => $val)
467
    {
468
      $this->_rootref[$key] = $val;
469
    }
470
471
    return true;
472
  }
473
474
  /**
475
  * Assign a single variable to a single key
476
  * @access public
477
  */
478
  function assign_var($varname, $varval)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
479
  {
480
    $this->_rootref[$varname] = $varval;
481
482
    return true;
483
  }
484
485
  /**
486
  * Assign key variable pairs from an array to a specified block
487
  * @access public
488
  */
489
  function assign_block_vars($blockname, $vararray)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
490
  {
491
    if (strpos($blockname, '.') !== false)
492
    {
493
      // Nested block.
494
      $blocks = explode('.', $blockname);
495
      $blockcount = sizeof($blocks) - 1;
496
497
      $str = &$this->_tpldata;
498
      for ($i = 0; $i < $blockcount; $i++)
499
      {
500
        $str = &$str[$blocks[$i]];
501
        $str = &$str[sizeof($str) - 1];
502
      }
503
504
      $s_row_count = isset($str[$blocks[$blockcount]]) ? sizeof($str[$blocks[$blockcount]]) : 0;
505
      $vararray['S_ROW_COUNT'] = $s_row_count;
506
507
      // Assign S_FIRST_ROW
508
      if (!$s_row_count)
509
      {
510
        $vararray['S_FIRST_ROW'] = true;
511
      }
512
513
      // Now the tricky part, we always assign S_LAST_ROW and remove the entry before
514
      // This is much more clever than going through the complete template data on display (phew)
515
      $vararray['S_LAST_ROW'] = true;
516
      if ($s_row_count > 0)
517
      {
518
        unset($str[$blocks[$blockcount]][($s_row_count - 1)]['S_LAST_ROW']);
519
      }
520
521
      // Now we add the block that we're actually assigning to.
522
      // We're adding a new iteration to this block with the given
523
      // variable assignments.
524
      $str[$blocks[$blockcount]][] = $vararray;
525
    }
526
    else
527
    {
528
      // Top-level block.
529
      $s_row_count = (isset($this->_tpldata[$blockname])) ? sizeof($this->_tpldata[$blockname]) : 0;
530
      $vararray['S_ROW_COUNT'] = $s_row_count;
531
532
      // Assign S_FIRST_ROW
533
      if (!$s_row_count)
534
      {
535
        $vararray['S_FIRST_ROW'] = true;
536
      }
537
538
      // We always assign S_LAST_ROW and remove the entry before
539
      $vararray['S_LAST_ROW'] = true;
540
      if ($s_row_count > 0)
541
      {
542
        unset($this->_tpldata[$blockname][($s_row_count - 1)]['S_LAST_ROW']);
543
      }
544
545
      // Add a new iteration to this block with the variable assignments we were given.
546
      $this->_tpldata[$blockname][] = $vararray;
547
    }
548
549
    return true;
550
  }
551
552
  /**
553
  * Change already assigned key variable pair (one-dimensional - single loop entry)
554
  *
555
  * An example of how to use this function:
556
  * {@example alter_block_array.php}
557
  *
558
  * @param  string  $blockname  the blockname, for example 'loop'
559
  * @param  array $vararray the var array to insert/add or merge
560
  * @param  mixed $key    Key to search for
561
  *
562
  * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position]
563
  *
564
  * int: Position [the position to change or insert at directly given]
565
  *
566
  * If key is false the position is set to 0
567
  * If key is true the position is set to the last entry
568
  *
569
  * @param  string  $mode   Mode to execute (valid modes are 'insert' and 'change')
570
  *
571
  * If insert, the vararray is inserted at the given position (position counting from zero).
572
  * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value).
573
  *
574
  * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array)
575
  * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars)
576
  *
577
  * @return bool false on error, true on success
578
  * @access public
579
  */
580
  function alter_block_array($blockname, $vararray, $key = false, $mode = 'insert')
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
581
  {
582
    if (strpos($blockname, '.') !== false)
583
    {
584
      // Nested blocks are not supported
585
      return false;
586
    }
587
588
    // Change key to zero (change first position) if false and to last position if true
589
    if ($key === false || $key === true)
590
    {
591
      $key = ($key === false) ? 0 : sizeof($this->_tpldata[$blockname]);
592
    }
593
594
    // Get correct position if array given
595
    if (is_array($key))
596
    {
597
      // Search array to get correct position
598
      list($search_key, $search_value) = @each($key);
599
600
      $key = NULL;
601
      foreach ($this->_tpldata[$blockname] as $i => $val_ary)
602
      {
603
        if ($val_ary[$search_key] === $search_value)
604
        {
605
          $key = $i;
606
          break;
607
        }
608
      }
609
610
      // key/value pair not found
611
      if ($key === NULL)
612
      {
613
        return false;
614
      }
615
    }
616
617
    // Insert Block
618
    if ($mode == 'insert')
619
    {
620
      // Make sure we are not exceeding the last iteration
621
      if ($key >= sizeof($this->_tpldata[$blockname]))
622
      {
623
        $key = sizeof($this->_tpldata[$blockname]);
624
        unset($this->_tpldata[$blockname][($key - 1)]['S_LAST_ROW']);
625
        $vararray['S_LAST_ROW'] = true;
626
      }
627
      else if ($key === 0)
628
      {
629
        unset($this->_tpldata[$blockname][0]['S_FIRST_ROW']);
630
        $vararray['S_FIRST_ROW'] = true;
631
      }
632
633
      // Re-position template blocks
634
      for ($i = sizeof($this->_tpldata[$blockname]); $i > $key; $i--)
635
      {
636
        $this->_tpldata[$blockname][$i] = $this->_tpldata[$blockname][$i-1];
637
        $this->_tpldata[$blockname][$i]['S_ROW_COUNT'] = $i;
638
      }
639
640
      // Insert vararray at given position
641
      $vararray['S_ROW_COUNT'] = $key;
642
      $this->_tpldata[$blockname][$key] = $vararray;
643
644
      return true;
645
    }
646
647
    // Which block to change?
648
    if ($mode == 'change')
649
    {
650
      if ($key == sizeof($this->_tpldata[$blockname]))
651
      {
652
        $key--;
653
      }
654
655
      $this->_tpldata[$blockname][$key] = array_merge($this->_tpldata[$blockname][$key], $vararray);
656
      return true;
657
    }
658
659
    return false;
660
  }
661
662
  /**
663
  * Include a separate template
664
  * @access private
665
  */
666
  function _tpl_include($filename, $include = true)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
667
  {
668
    // This is used to access global vars
669
    // global $lang, $config, $user; // Not needed!
670
671
    $handle = $filename;
672
    $this->filename[$handle] = $filename;
673
    $this->files[$handle] = $this->root . '/' . $filename;
674
    if ($this->inherit_root)
675
    {
676
      $this->files_inherit[$handle] = $this->inherit_root . '/' . $filename;
677
    }
678
679
    $filename = $this->_tpl_load($handle);
680
681
    if ($include)
682
    {
683
684
      if ($filename)
685
      {
686
        include($filename);
687
        return;
688
      }
689
      $this->evaluate($this->compiled_code[$handle]);
690
    }
691
  }
692
693
  /**
694
  * Include a php-file
695
  * @access private
696
  */
697
  function _php_include($filename)
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
698
  {
699
    $file = $this->rootPhysical . $filename;
700
701
    if (!file_exists($file))
702
    {
703
      // trigger_error cannot be used here, as the output already started
704
      echo 'template->_php_include(): File ' . htmlspecialchars($file) . ' does not exist or is empty';
705
      return;
706
    }
707
    include($file);
708
  }
709
710
  /**
711
  * Assign key variable pairs from an array with block support
712
  * @access public
713
  */
714
  function assign_recursive($values, $name = '')
715
  {
716
    if(isset($values['.']))
717
    {
718
      $values_extra = $values['.'];
719
      unset($values['.']);
720
    }
721
722
    if(!$name)
723
    {
724
      $this->assign_vars($values);
725
    }
726
    else
727
    {
728
      $this->assign_block_vars($name, $values);
729
    }
730
731
    if(isset($values_extra))
732
    {
733
      foreach($values_extra as $sub_array_name => $sub_array)
734
      {
735
        $new_name = $name . ($name ? '.' : '') . $sub_array_name;
736
        foreach($sub_array as $sub_element)
737
        {
738
          $this->assign_recursive($sub_element, $new_name);
739
        }
740
      }
741
    }
742
  }
743
744
  /**
745
   * This function will be called from compiled template to re-render variables - i.e. allow late binding of values aka accessing variable value by it's name in template var
746
   *
747
   * @param string $stringTag
748
   *
749
   * @return mixed|string
750
   */
751
  public function reRender($stringTag) {
752
    $tplTag = new PTLTag($stringTag, $this);
753
    $result = $tplTag->resolved;
754
    $this->compiler->compile_var_tags($result);
755
    $this->evaluate($result);
756
757
    return $result;
758
  }
759
760
  protected function evaluate($code) {
761
    // This is used to access global vars
762
    // global $lang, $config, $user; // Not needed
763
764
    eval(' ?>' . $code . '<?php ');
765
  }
766
767
}
768