/packages/Output/Smarty/Core/sysplugins/smarty_internal_debug.php
PHP | 430 lines | 279 code | 25 blank | 126 comment | 76 complexity | cc13ed9a19762e60c1f76c2ffb428c85 MD5 | raw file
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 */
17class 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)) {
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
121 $key = $this->get_key($template);
122 }
123 $this->template_data[ $this->index ][ $key ][ 'compile_time' ] +=
124 microtime(true) - $this->template_data[ $this->index ][ $key ][ 'start_time' ];
125 }
126
127 /**
128 * Start logging of render time
129 *
130 * @param \Smarty_Internal_Template $template
131 */
132 public function start_render(Smarty_Internal_Template $template)
133 {
134 $key = $this->get_key($template);
135 $this->template_data[ $this->index ][ $key ][ 'start_time' ] = microtime(true);
136 }
137
138 /**
139 * End logging of compile time
140 *
141 * @param \Smarty_Internal_Template $template
142 */
143 public function end_render(Smarty_Internal_Template $template)
144 {
145 $key = $this->get_key($template);
146 $this->template_data[ $this->index ][ $key ][ 'render_time' ] +=
147 microtime(true) - $this->template_data[ $this->index ][ $key ][ 'start_time' ];
148 }
149
150 /**
151 * Start logging of cache time
152 *
153 * @param \Smarty_Internal_Template $template cached template
154 */
155 public function start_cache(Smarty_Internal_Template $template)
156 {
157 $key = $this->get_key($template);
158 $this->template_data[ $this->index ][ $key ][ 'start_time' ] = microtime(true);
159 }
160
161 /**
162 * End logging of cache time
163 *
164 * @param \Smarty_Internal_Template $template cached template
165 */
166 public function end_cache(Smarty_Internal_Template $template)
167 {
168 $key = $this->get_key($template);
169 $this->template_data[ $this->index ][ $key ][ 'cache_time' ] +=
170 microtime(true) - $this->template_data[ $this->index ][ $key ][ 'start_time' ];
171 }
172
173 /**
174 * Register template object
175 *
176 * @param \Smarty_Internal_Template $template cached template
177 */
178 public function register_template(Smarty_Internal_Template $template)
179 {
180 }
181
182 /**
183 * Register data object
184 *
185 * @param \Smarty_Data $data data object
186 */
187 public static function register_data(Smarty_Data $data)
188 {
189 }
190
191 /**
192 * Opens a window for the Smarty Debugging Console and display the data
193 *
194 * @param Smarty_Internal_Template|Smarty $obj object to debug
195 * @param bool $full
196 */
197 public function display_debug($obj, $full = false)
198 {
199 if (!$full) {
200 $this->offset ++;
201 $savedIndex = $this->index;
202 $this->index = 9999;
203 }
204 if ($obj->_objType == 1) {
205 $smarty = $obj;
206 } else {
207 $smarty = $obj->smarty;
208 }
209 // create fresh instance of smarty for displaying the debug console
210 // to avoid problems if the application did overload the Smarty class
211 $debObj = new Smarty();
212 // copy the working dirs from application
213 $debObj->setCompileDir($smarty->getCompileDir());
214 // init properties by hand as user may have edited the original Smarty class
215 $debObj->setPluginsDir(is_dir(__DIR__ . '/../plugins') ? __DIR__ . '/../plugins' : $smarty->getPluginsDir());
216 $debObj->force_compile = false;
217 $debObj->compile_check = true;
218 $debObj->left_delimiter = '{';
219 $debObj->right_delimiter = '}';
220 $debObj->security_policy = null;
221 $debObj->debugging = false;
222 $debObj->debugging_ctrl = 'NONE';
223 $debObj->error_reporting = E_ALL & ~E_NOTICE;
224 $debObj->debug_tpl = isset($smarty->debug_tpl) ? $smarty->debug_tpl : 'file:' . __DIR__ . '/../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 = false;
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
242 $_template = new Smarty_Internal_Template($debObj->debug_tpl, $debObj);
243 if ($obj->_objType == 2) {
244 $_template->assign('template_name', $obj->source->type . ':' . $obj->source->name);
245 }
246 if ($obj->_objType == 1 || $full) {
247 $_template->assign('template_data', $this->template_data[ $this->index ]);
248 } else {
249 $_template->assign('template_data', null);
250 }
251 $_template->assign('assigned_vars', $_assigned_vars);
252 $_template->assign('config_vars', $_config_vars);
253 $_template->assign('execution_time', microtime(true) - $smarty->start_time);
254 $_template->assign('display_mode', $debugging == 2 || !$full);
255 $_template->assign('offset', $this->offset * 50);
256 echo $_template->fetch();
257 if (isset($full)) {
258 $this->index --;
259 }
260 if (!$full) {
261 $this->index = $savedIndex;
262 }
263 }
264
265 /**
266 * Recursively gets variables from all template/data scopes
267 *
268 * @param Smarty_Internal_Template|Smarty_Data $obj object to debug
269 *
270 * @return StdClass
271 */
272 public function get_debug_vars($obj)
273 {
274 $config_vars = array();
275 foreach ($obj->config_vars as $key => $var) {
276 $config_vars[ $key ][ 'value' ] = $var;
277 if ($obj->_objType == 2) {
278 $config_vars[ $key ][ 'scope' ] = $obj->source->type . ':' . $obj->source->name;
279 } elseif ($obj->_objType == 4) {
280 $tpl_vars[ $key ][ 'scope' ] = $obj->dataObjectName;
281 } else {
282 $config_vars[ $key ][ 'scope' ] = 'Smarty object';
283 }
284 }
285 $tpl_vars = array();
286 foreach ($obj->tpl_vars as $key => $var) {
287 foreach ($var as $varkey => $varvalue) {
288 if ($varkey == 'value') {
289 $tpl_vars[ $key ][ $varkey ] = $varvalue;
290 } else {
291 if ($varkey == 'nocache') {
292 if ($varvalue == true) {
293 $tpl_vars[ $key ][ $varkey ] = $varvalue;
294 }
295 } else {
296 if ($varkey != 'scope' || $varvalue !== 0) {
297 $tpl_vars[ $key ][ 'attributes' ][ $varkey ] = $varvalue;
298 }
299 }
300 }
301 }
302 if ($obj->_objType == 2) {
303 $tpl_vars[ $key ][ 'scope' ] = $obj->source->type . ':' . $obj->source->name;
304 } elseif ($obj->_objType == 4) {
305 $tpl_vars[ $key ][ 'scope' ] = $obj->dataObjectName;
306 } else {
307 $tpl_vars[ $key ][ 'scope' ] = 'Smarty object';
308 }
309 }
310
311 if (isset($obj->parent)) {
312 $parent = $this->get_debug_vars($obj->parent);
313 foreach ($parent->tpl_vars as $name => $pvar) {
314 if (isset($tpl_vars[ $name ]) && $tpl_vars[ $name ][ 'value' ] === $pvar[ 'value' ]) {
315 $tpl_vars[ $name ][ 'scope' ] = $pvar[ 'scope' ];
316 }
317 }
318 $tpl_vars = array_merge($parent->tpl_vars, $tpl_vars);
319
320 foreach ($parent->config_vars as $name => $pvar) {
321 if (isset($config_vars[ $name ]) && $config_vars[ $name ][ 'value' ] === $pvar[ 'value' ]) {
322 $config_vars[ $name ][ 'scope' ] = $pvar[ 'scope' ];
323 }
324 }
325 $config_vars = array_merge($parent->config_vars, $config_vars);
326 } else {
327 foreach (Smarty::$global_tpl_vars as $key => $var) {
328 if (!array_key_exists($key, $tpl_vars)) {
329 foreach ($var as $varkey => $varvalue) {
330 if ($varkey == 'value') {
331 $tpl_vars[ $key ][ $varkey ] = $varvalue;
332 } else {
333 if ($varkey == 'nocache') {
334 if ($varvalue == true) {
335 $tpl_vars[ $key ][ $varkey ] = $varvalue;
336 }
337 } else {
338 if ($varkey != 'scope' || $varvalue !== 0) {
339 $tpl_vars[ $key ][ 'attributes' ][ $varkey ] = $varvalue;
340 }
341 }
342 }
343 }
344 $tpl_vars[ $key ][ 'scope' ] = 'Global';
345 }
346 }
347 }
348
349 return (object) array('tpl_vars' => $tpl_vars, 'config_vars' => $config_vars);
350 }
351
352 /**
353 * Return key into $template_data for template
354 *
355 * @param \Smarty_Internal_Template $template template object
356 *
357 * @return string key into $template_data
358 */
359 private function get_key(Smarty_Internal_Template $template)
360 {
361 static $_is_stringy = array('string' => true, 'eval' => true);
362 // calculate Uid if not already done
363 if ($template->source->uid == '') {
364 $template->source->filepath;
365 }
366 $key = $template->source->uid;
367 if (isset($this->template_data[ $this->index ][ $key ])) {
368 return $key;
369 } else {
370 if (isset($_is_stringy[ $template->source->type ])) {
371 $this->template_data[ $this->index ][ $key ][ 'name' ] =
372 '\'' . substr($template->source->name, 0, 25) . '...\'';
373 } else {
374 $this->template_data[ $this->index ][ $key ][ 'name' ] = $template->source->filepath;
375 }
376 $this->template_data[ $this->index ][ $key ][ 'compile_time' ] = 0;
377 $this->template_data[ $this->index ][ $key ][ 'render_time' ] = 0;
378 $this->template_data[ $this->index ][ $key ][ 'cache_time' ] = 0;
379 $this->template_data[ $this->index ][ $key ][ 'total_time' ] = 0;
380
381 return $key;
382 }
383 }
384
385 /**
386 * Ignore template
387 *
388 * @param \Smarty_Internal_Template $template
389 */
390 public function ignore(Smarty_Internal_Template $template)
391 {
392 // calculate Uid if not already done
393 if ($template->source->uid == '') {
394 $template->source->filepath;
395 }
396 $this->ignore_uid[ $template->source->uid ] = true;
397 }
398
399 /**
400 * handle 'URL' debugging mode
401 *
402 * @param Smarty $smarty
403 */
404 public function debugUrl(Smarty $smarty)
405 {
406 if (isset($_SERVER[ 'QUERY_STRING' ])) {
407 $_query_string = $_SERVER[ 'QUERY_STRING' ];
408 } else {
409 $_query_string = '';
410 }
411 if (false !== strpos($_query_string, $smarty->smarty_debug_id)) {
412 if (false !== strpos($_query_string, $smarty->smarty_debug_id . '=on')) {
413 // enable debugging for this browser session
414 setcookie('SMARTY_DEBUG', true);
415 $smarty->debugging = true;
416 } elseif (false !== strpos($_query_string, $smarty->smarty_debug_id . '=off')) {
417 // disable debugging for this browser session
418 setcookie('SMARTY_DEBUG', false);
419 $smarty->debugging = false;
420 } else {
421 // enable debugging for this page
422 $smarty->debugging = true;
423 }
424 } else {
425 if (isset($_COOKIE[ 'SMARTY_DEBUG' ])) {
426 $smarty->debugging = true;
427 }
428 }
429 }
430}