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