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() |
|
|
|
|
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) |
|
|
|
|
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) |
|
|
|
|
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() |
|
|
|
|
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) |
|
|
|
|
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) |
|
|
|
|
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) |
|
|
|
|
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) |
|
|
|
|
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); |
|
|
|
|
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 . ' |
|
|
|
|
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']; |
|
|
|
|
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) |
|
|
|
|
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) |
|
|
|
|
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) |
|
|
|
|
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') |
|
|
|
|
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) |
|
|
|
|
667
|
|
|
{ |
668
|
|
|
// This is used to access global vars |
669
|
|
|
global $lang, $config, $user; |
|
|
|
|
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) |
|
|
|
|
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; |
|
|
|
|
763
|
|
|
|
764
|
|
|
eval(' ?>' . $code . '<?php '); |
|
|
|
|
765
|
|
|
} |
766
|
|
|
|
767
|
|
|
} |
768
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.