1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Smarty Internal Plugin Debug |
4
|
|
|
* Class to collect data for the Smarty Debugging Console |
5
|
|
|
* |
6
|
|
|
* @package Smarty |
7
|
|
|
* @subpackage Debug |
8
|
|
|
* @author Uwe Tews |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Smarty Internal Plugin Debug Class |
13
|
|
|
* |
14
|
|
|
* @package Smarty |
15
|
|
|
* @subpackage Debug |
16
|
|
|
*/ |
17
|
|
|
class Smarty_Internal_Debug extends Smarty_Internal_Data |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* template data |
21
|
|
|
* |
22
|
|
|
* @var array |
23
|
|
|
*/ |
24
|
|
|
public $template_data = array(); |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* List of uid's which shall be ignored |
28
|
|
|
* |
29
|
|
|
* @var array |
30
|
|
|
*/ |
31
|
|
|
public $ignore_uid = array(); |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Index of display() and fetch() calls |
35
|
|
|
* |
36
|
|
|
* @var int |
37
|
|
|
*/ |
38
|
|
|
public $index = 0; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Counter for window offset |
42
|
|
|
* |
43
|
|
|
* @var int |
44
|
|
|
*/ |
45
|
|
|
public $offset = 0; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Start logging template |
49
|
|
|
* |
50
|
|
|
* @param \Smarty_Internal_Template $template template |
51
|
|
|
* @param null $mode true: display false: fetch null: subtemplate |
52
|
|
|
*/ |
53
|
|
|
public function start_template(Smarty_Internal_Template $template, $mode = null) |
54
|
|
|
{ |
55
|
|
|
if (isset($mode) && !$template->_isSubTpl()) { |
56
|
|
|
$this->index++; |
57
|
|
|
$this->offset++; |
58
|
|
|
$this->template_data[ $this->index ] = null; |
59
|
|
|
} |
60
|
|
|
$key = $this->get_key($template); |
61
|
|
|
$this->template_data[ $this->index ][ $key ][ 'start_template_time' ] = microtime(true); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* End logging of cache time |
66
|
|
|
* |
67
|
|
|
* @param \Smarty_Internal_Template $template cached template |
68
|
|
|
*/ |
69
|
|
|
public function end_template(Smarty_Internal_Template $template) |
70
|
|
|
{ |
71
|
|
|
$key = $this->get_key($template); |
72
|
|
|
$this->template_data[ $this->index ][ $key ][ 'total_time' ] += |
73
|
|
|
microtime(true) - $this->template_data[ $this->index ][ $key ][ 'start_template_time' ]; |
74
|
|
|
//$this->template_data[$this->index][$key]['properties'] = $template->properties; |
|
|
|
|
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Start logging of compile time |
79
|
|
|
* |
80
|
|
|
* @param \Smarty_Internal_Template $template |
81
|
|
|
*/ |
82
|
|
|
public function start_compile(Smarty_Internal_Template $template) |
83
|
|
|
{ |
84
|
|
|
static $_is_stringy = array('string' => true, 'eval' => true); |
85
|
|
|
if (!empty($template->compiler->trace_uid)) { |
86
|
|
|
$key = $template->compiler->trace_uid; |
87
|
|
|
if (!isset($this->template_data[ $this->index ][ $key ])) { |
88
|
|
|
if (isset($_is_stringy[ $template->source->type ])) { |
89
|
|
|
$this->template_data[ $this->index ][ $key ][ 'name' ] = |
90
|
|
|
'\'' . substr($template->source->name, 0, 25) . '...\''; |
91
|
|
|
} else { |
92
|
|
|
$this->template_data[ $this->index ][ $key ][ 'name' ] = $template->source->filepath; |
93
|
|
|
} |
94
|
|
|
$this->template_data[ $this->index ][ $key ][ 'compile_time' ] = 0; |
95
|
|
|
$this->template_data[ $this->index ][ $key ][ 'render_time' ] = 0; |
96
|
|
|
$this->template_data[ $this->index ][ $key ][ 'cache_time' ] = 0; |
97
|
|
|
} |
98
|
|
|
} else { |
99
|
|
|
if (isset($this->ignore_uid[ $template->source->uid ])) { |
100
|
|
|
return; |
101
|
|
|
} |
102
|
|
|
$key = $this->get_key($template); |
103
|
|
|
} |
104
|
|
|
$this->template_data[ $this->index ][ $key ][ 'start_time' ] = microtime(true); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* End logging of compile time |
109
|
|
|
* |
110
|
|
|
* @param \Smarty_Internal_Template $template |
111
|
|
|
*/ |
112
|
|
|
public function end_compile(Smarty_Internal_Template $template) |
113
|
|
|
{ |
114
|
|
|
if (!empty($template->compiler->trace_uid)) { |
115
|
|
|
$key = $template->compiler->trace_uid; |
116
|
|
|
} else { |
117
|
|
|
if (isset($this->ignore_uid[ $template->source->uid ])) { |
118
|
|
|
return; |
119
|
|
|
} |
120
|
|
|
$key = $this->get_key($template); |
121
|
|
|
} |
122
|
|
|
$this->template_data[ $this->index ][ $key ][ 'compile_time' ] += |
123
|
|
|
microtime(true) - $this->template_data[ $this->index ][ $key ][ 'start_time' ]; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Start logging of render time |
128
|
|
|
* |
129
|
|
|
* @param \Smarty_Internal_Template $template |
130
|
|
|
*/ |
131
|
|
|
public function start_render(Smarty_Internal_Template $template) |
132
|
|
|
{ |
133
|
|
|
$key = $this->get_key($template); |
134
|
|
|
$this->template_data[ $this->index ][ $key ][ 'start_time' ] = microtime(true); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* End logging of compile time |
139
|
|
|
* |
140
|
|
|
* @param \Smarty_Internal_Template $template |
141
|
|
|
*/ |
142
|
|
|
public function end_render(Smarty_Internal_Template $template) |
143
|
|
|
{ |
144
|
|
|
$key = $this->get_key($template); |
145
|
|
|
$this->template_data[ $this->index ][ $key ][ 'render_time' ] += |
146
|
|
|
microtime(true) - $this->template_data[ $this->index ][ $key ][ 'start_time' ]; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Start logging of cache time |
151
|
|
|
* |
152
|
|
|
* @param \Smarty_Internal_Template $template cached template |
153
|
|
|
*/ |
154
|
|
|
public function start_cache(Smarty_Internal_Template $template) |
155
|
|
|
{ |
156
|
|
|
$key = $this->get_key($template); |
157
|
|
|
$this->template_data[ $this->index ][ $key ][ 'start_time' ] = microtime(true); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* End logging of cache time |
162
|
|
|
* |
163
|
|
|
* @param \Smarty_Internal_Template $template cached template |
164
|
|
|
*/ |
165
|
|
|
public function end_cache(Smarty_Internal_Template $template) |
166
|
|
|
{ |
167
|
|
|
$key = $this->get_key($template); |
168
|
|
|
$this->template_data[ $this->index ][ $key ][ 'cache_time' ] += |
169
|
|
|
microtime(true) - $this->template_data[ $this->index ][ $key ][ 'start_time' ]; |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* Register template object |
174
|
|
|
* |
175
|
|
|
* @param \Smarty_Internal_Template $template cached template |
176
|
|
|
*/ |
177
|
|
|
public function register_template(Smarty_Internal_Template $template) |
|
|
|
|
178
|
|
|
{ |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Register data object |
183
|
|
|
* |
184
|
|
|
* @param \Smarty_Data $data data object |
185
|
|
|
*/ |
186
|
|
|
public static function register_data(Smarty_Data $data) |
|
|
|
|
187
|
|
|
{ |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* Opens a window for the Smarty Debugging Console and display the data |
192
|
|
|
* |
193
|
|
|
* @param Smarty_Internal_Template|Smarty $obj object to debug |
194
|
|
|
* @param bool $full |
195
|
|
|
* |
196
|
|
|
* @throws \Exception |
197
|
|
|
* @throws \SmartyException |
198
|
|
|
*/ |
199
|
|
|
public function display_debug($obj, $full = false) |
200
|
|
|
{ |
201
|
|
|
if (!$full) { |
202
|
|
|
$this->offset++; |
203
|
|
|
$savedIndex = $this->index; |
204
|
|
|
$this->index = 9999; |
205
|
|
|
} |
206
|
|
|
$smarty = $obj->_getSmartyObj(); |
207
|
|
|
// create fresh instance of smarty for displaying the debug console |
208
|
|
|
// to avoid problems if the application did overload the Smarty class |
209
|
|
|
$debObj = new Smarty(); |
210
|
|
|
// copy the working dirs from application |
211
|
|
|
$debObj->setCompileDir($smarty->getCompileDir()); |
212
|
|
|
// init properties by hand as user may have edited the original Smarty class |
213
|
|
|
$debObj->setPluginsDir(is_dir(dirname(__FILE__) . '/../plugins') ? dirname(__FILE__) . |
214
|
|
|
'/../plugins' : $smarty->getPluginsDir()); |
215
|
|
|
$debObj->force_compile = false; |
216
|
|
|
$debObj->compile_check = Smarty::COMPILECHECK_ON; |
217
|
|
|
$debObj->left_delimiter = '{'; |
218
|
|
|
$debObj->right_delimiter = '}'; |
219
|
|
|
$debObj->security_policy = null; |
220
|
|
|
$debObj->debugging = false; |
221
|
|
|
$debObj->debugging_ctrl = 'NONE'; |
222
|
|
|
$debObj->error_reporting = E_ALL & ~E_NOTICE; |
223
|
|
|
$debObj->debug_tpl = |
224
|
|
|
isset($smarty->debug_tpl) ? $smarty->debug_tpl : 'file:' . dirname(__FILE__) . '/../debug.tpl'; |
225
|
|
|
$debObj->registered_plugins = array(); |
226
|
|
|
$debObj->registered_resources = array(); |
227
|
|
|
$debObj->registered_filters = array(); |
228
|
|
|
$debObj->autoload_filters = array(); |
229
|
|
|
$debObj->default_modifiers = array(); |
230
|
|
|
$debObj->escape_html = true; |
231
|
|
|
$debObj->caching = Smarty::CACHING_OFF; |
232
|
|
|
$debObj->compile_id = null; |
233
|
|
|
$debObj->cache_id = null; |
234
|
|
|
// prepare information of assigned variables |
235
|
|
|
$ptr = $this->get_debug_vars($obj); |
|
|
|
|
236
|
|
|
$_assigned_vars = $ptr->tpl_vars; |
237
|
|
|
ksort($_assigned_vars); |
238
|
|
|
$_config_vars = $ptr->config_vars; |
239
|
|
|
ksort($_config_vars); |
240
|
|
|
$debugging = $smarty->debugging; |
241
|
|
|
$_template = new Smarty_Internal_Template($debObj->debug_tpl, $debObj); |
242
|
|
|
if ($obj->_isTplObj()) { |
243
|
|
|
$_template->assign('template_name', $obj->source->type . ':' . $obj->source->name); |
244
|
|
|
} |
245
|
|
|
if ($obj->_objType === 1 || $full) { |
246
|
|
|
$_template->assign('template_data', $this->template_data[ $this->index ]); |
247
|
|
|
} else { |
248
|
|
|
$_template->assign('template_data', null); |
249
|
|
|
} |
250
|
|
|
$_template->assign('assigned_vars', $_assigned_vars); |
251
|
|
|
$_template->assign('config_vars', $_config_vars); |
252
|
|
|
$_template->assign('execution_time', microtime(true) - $smarty->start_time); |
253
|
|
|
$_template->assign('display_mode', $debugging === 2 || !$full); |
254
|
|
|
$_template->assign('offset', $this->offset * 50); |
255
|
|
|
echo $_template->fetch(); |
256
|
|
|
if (isset($full)) { |
257
|
|
|
$this->index--; |
258
|
|
|
} |
259
|
|
|
if (!$full) { |
|
|
|
|
260
|
|
|
$this->index = $savedIndex; |
|
|
|
|
261
|
|
|
} |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* Recursively gets variables from all template/data scopes |
266
|
|
|
* |
267
|
|
|
* @param Smarty_Internal_Template|Smarty_Data $obj object to debug |
268
|
|
|
* |
269
|
|
|
* @return StdClass |
270
|
|
|
*/ |
271
|
|
|
public function get_debug_vars($obj) |
272
|
|
|
{ |
273
|
|
|
$config_vars = array(); |
274
|
|
|
foreach ($obj->config_vars as $key => $var) { |
275
|
|
|
$config_vars[ $key ][ 'value' ] = $var; |
276
|
|
|
if ($obj->_isTplObj()) { |
277
|
|
|
$config_vars[ $key ][ 'scope' ] = $obj->source->type . ':' . $obj->source->name; |
278
|
|
|
} elseif ($obj->_isDataObj()) { |
279
|
|
|
$tpl_vars[ $key ][ 'scope' ] = $obj->dataObjectName; |
|
|
|
|
280
|
|
|
} else { |
281
|
|
|
$config_vars[ $key ][ 'scope' ] = 'Smarty object'; |
282
|
|
|
} |
283
|
|
|
} |
284
|
|
|
$tpl_vars = array(); |
285
|
|
|
foreach ($obj->tpl_vars as $key => $var) { |
286
|
|
|
foreach ($var as $varkey => $varvalue) { |
287
|
|
|
if ($varkey === 'value') { |
288
|
|
|
$tpl_vars[ $key ][ $varkey ] = $varvalue; |
289
|
|
|
} else { |
290
|
|
|
if ($varkey === 'nocache') { |
291
|
|
|
if ($varvalue === true) { |
292
|
|
|
$tpl_vars[ $key ][ $varkey ] = $varvalue; |
293
|
|
|
} |
294
|
|
|
} else { |
295
|
|
|
if ($varkey !== 'scope' || $varvalue !== 0) { |
296
|
|
|
$tpl_vars[ $key ][ 'attributes' ][ $varkey ] = $varvalue; |
297
|
|
|
} |
298
|
|
|
} |
299
|
|
|
} |
300
|
|
|
} |
301
|
|
|
if ($obj->_isTplObj()) { |
302
|
|
|
$tpl_vars[ $key ][ 'scope' ] = $obj->source->type . ':' . $obj->source->name; |
303
|
|
|
} elseif ($obj->_isDataObj()) { |
304
|
|
|
$tpl_vars[ $key ][ 'scope' ] = $obj->dataObjectName; |
305
|
|
|
} else { |
306
|
|
|
$tpl_vars[ $key ][ 'scope' ] = 'Smarty object'; |
307
|
|
|
} |
308
|
|
|
} |
309
|
|
|
if (isset($obj->parent)) { |
310
|
|
|
$parent = $this->get_debug_vars($obj->parent); |
311
|
|
|
foreach ($parent->tpl_vars as $name => $pvar) { |
312
|
|
|
if (isset($tpl_vars[ $name ]) && $tpl_vars[ $name ][ 'value' ] === $pvar[ 'value' ]) { |
313
|
|
|
$tpl_vars[ $name ][ 'scope' ] = $pvar[ 'scope' ]; |
314
|
|
|
} |
315
|
|
|
} |
316
|
|
|
$tpl_vars = array_merge($parent->tpl_vars, $tpl_vars); |
317
|
|
|
foreach ($parent->config_vars as $name => $pvar) { |
318
|
|
|
if (isset($config_vars[ $name ]) && $config_vars[ $name ][ 'value' ] === $pvar[ 'value' ]) { |
319
|
|
|
$config_vars[ $name ][ 'scope' ] = $pvar[ 'scope' ]; |
320
|
|
|
} |
321
|
|
|
} |
322
|
|
|
$config_vars = array_merge($parent->config_vars, $config_vars); |
323
|
|
|
} else { |
324
|
|
|
foreach (Smarty::$global_tpl_vars as $key => $var) { |
325
|
|
|
if (!array_key_exists($key, $tpl_vars)) { |
326
|
|
|
foreach ($var as $varkey => $varvalue) { |
327
|
|
|
if ($varkey === 'value') { |
328
|
|
|
$tpl_vars[ $key ][ $varkey ] = $varvalue; |
329
|
|
|
} else { |
330
|
|
|
if ($varkey === 'nocache') { |
331
|
|
|
if ($varvalue === true) { |
332
|
|
|
$tpl_vars[ $key ][ $varkey ] = $varvalue; |
333
|
|
|
} |
334
|
|
|
} else { |
335
|
|
|
if ($varkey !== 'scope' || $varvalue !== 0) { |
336
|
|
|
$tpl_vars[ $key ][ 'attributes' ][ $varkey ] = $varvalue; |
337
|
|
|
} |
338
|
|
|
} |
339
|
|
|
} |
340
|
|
|
} |
341
|
|
|
$tpl_vars[ $key ][ 'scope' ] = 'Global'; |
342
|
|
|
} |
343
|
|
|
} |
344
|
|
|
} |
345
|
|
|
return (object)array('tpl_vars' => $tpl_vars, 'config_vars' => $config_vars); |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
/** |
349
|
|
|
* Return key into $template_data for template |
350
|
|
|
* |
351
|
|
|
* @param \Smarty_Internal_Template $template template object |
352
|
|
|
* |
353
|
|
|
* @return string key into $template_data |
354
|
|
|
*/ |
355
|
|
|
private function get_key(Smarty_Internal_Template $template) |
356
|
|
|
{ |
357
|
|
|
static $_is_stringy = array('string' => true, 'eval' => true); |
358
|
|
|
// calculate Uid if not already done |
359
|
|
|
if ($template->source->uid === '') { |
360
|
|
|
$template->source->filepath; |
361
|
|
|
} |
362
|
|
|
$key = $template->source->uid; |
363
|
|
|
if (isset($this->template_data[ $this->index ][ $key ])) { |
364
|
|
|
return $key; |
365
|
|
|
} else { |
366
|
|
|
if (isset($_is_stringy[ $template->source->type ])) { |
367
|
|
|
$this->template_data[ $this->index ][ $key ][ 'name' ] = |
368
|
|
|
'\'' . substr($template->source->name, 0, 25) . '...\''; |
369
|
|
|
} else { |
370
|
|
|
$this->template_data[ $this->index ][ $key ][ 'name' ] = $template->source->filepath; |
371
|
|
|
} |
372
|
|
|
$this->template_data[ $this->index ][ $key ][ 'compile_time' ] = 0; |
373
|
|
|
$this->template_data[ $this->index ][ $key ][ 'render_time' ] = 0; |
374
|
|
|
$this->template_data[ $this->index ][ $key ][ 'cache_time' ] = 0; |
375
|
|
|
$this->template_data[ $this->index ][ $key ][ 'total_time' ] = 0; |
376
|
|
|
return $key; |
377
|
|
|
} |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
/** |
381
|
|
|
* Ignore template |
382
|
|
|
* |
383
|
|
|
* @param \Smarty_Internal_Template $template |
384
|
|
|
*/ |
385
|
|
|
public function ignore(Smarty_Internal_Template $template) |
386
|
|
|
{ |
387
|
|
|
// calculate Uid if not already done |
388
|
|
|
if ($template->source->uid === '') { |
389
|
|
|
$template->source->filepath; |
390
|
|
|
} |
391
|
|
|
$this->ignore_uid[ $template->source->uid ] = true; |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
/** |
395
|
|
|
* handle 'URL' debugging mode |
396
|
|
|
* |
397
|
|
|
* @param Smarty $smarty |
398
|
|
|
*/ |
399
|
|
|
public function debugUrl(Smarty $smarty) |
|
|
|
|
400
|
|
|
{ |
401
|
|
|
if (isset($_SERVER[ 'QUERY_STRING' ])) { |
402
|
|
|
$_query_string = $_SERVER[ 'QUERY_STRING' ]; |
403
|
|
|
} else { |
404
|
|
|
$_query_string = ''; |
405
|
|
|
} |
406
|
|
|
if (false !== strpos($_query_string, $smarty->smarty_debug_id)) { |
407
|
|
|
if (false !== strpos($_query_string, $smarty->smarty_debug_id . '=on')) { |
408
|
|
|
// enable debugging for this browser session |
409
|
|
|
setcookie('SMARTY_DEBUG', true); |
410
|
|
|
$smarty->debugging = true; |
411
|
|
|
} elseif (false !== strpos($_query_string, $smarty->smarty_debug_id . '=off')) { |
412
|
|
|
// disable debugging for this browser session |
413
|
|
|
setcookie('SMARTY_DEBUG', false); |
414
|
|
|
$smarty->debugging = false; |
415
|
|
|
} else { |
416
|
|
|
// enable debugging for this page |
417
|
|
|
$smarty->debugging = true; |
418
|
|
|
} |
419
|
|
|
} else { |
420
|
|
|
if (isset($_COOKIE[ 'SMARTY_DEBUG' ])) { |
421
|
|
|
$smarty->debugging = true; |
422
|
|
|
} |
423
|
|
|
} |
424
|
|
|
} |
425
|
|
|
} |
426
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.