[ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 3 /* 4 * This file is part of the symfony package. 5 * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11 /** 12 * sfWebDebug creates debug information for easy debugging in the browser. 13 * 14 * @package symfony 15 * @subpackage debug 16 * @author Fabien Potencier <fabien.potencier@symfony-project.com> 17 * @version SVN: $Id: sfWebDebug.class.php 3211 2007-01-10 20:51:39Z fabien $ 18 */ 19 class sfWebDebug 20 { 21 protected 22 $log = array(), 23 $short_log = array(), 24 $max_priority = 1000, 25 $types = array(), 26 $last_time_log = -1; 27 28 protected static 29 $instance = null; 30 31 public function initialize() 32 { 33 } 34 35 /** 36 * Retrieves the singleton instance of this class. 37 * 38 * @return sfWebDebug A sfWebDebug implementation instance 39 */ 40 public static function getInstance() 41 { 42 if (!isset(self::$instance)) 43 { 44 $class = __CLASS__; 45 self::$instance = new $class(); 46 self::$instance->initialize(); 47 } 48 49 return self::$instance; 50 } 51 52 /** 53 * Registers javascripts and stylesheets needed for the web debug toolbar. 54 */ 55 public function registerAssets() 56 { 57 $response = sfContext::getInstance()->getResponse(); 58 59 // register our css and js 60 $response->addJavascript(sfConfig::get('sf_web_debug_web_dir').'/js/main'); 61 $response->addStylesheet(sfConfig::get('sf_web_debug_web_dir').'/css/main'); 62 } 63 64 /** 65 * Logs a short message to be displayed in the web debug toolbar. 66 * 67 * @param string The message string 68 */ 69 public function logShortMessage($message) 70 { 71 $this->short_log[] = $message; 72 } 73 74 /** 75 * Logs a message to the web debug toolbar. 76 * 77 * @param array An array of parameter 78 * 79 * @see sfWebDebugLogger 80 */ 81 public function log($logEntry) 82 { 83 // elapsed time 84 if ($this->last_time_log == -1) 85 { 86 $this->last_time_log = sfConfig::get('sf_timer_start'); 87 } 88 89 $this->last_time_log = microtime(true); 90 91 // update max priority 92 if ($logEntry['priority'] < $this->max_priority) 93 { 94 $this->max_priority = $logEntry['priority']; 95 } 96 97 // update types 98 if (!isset($this->types[$logEntry['type']])) 99 { 100 $this->types[$logEntry['type']] = 1; 101 } 102 else 103 { 104 ++$this->types[$logEntry['type']]; 105 } 106 107 $this->log[] = $logEntry; 108 } 109 110 /** 111 * Loads helpers needed for the web debug toolbar. 112 */ 113 protected function loadHelpers() 114 { 115 sfLoader::loadHelpers(array('Helper', 'Url', 'Asset', 'Tag', 'Javascript')); 116 } 117 118 /** 119 * Formats a log line. 120 * 121 * @param string The log line to format 122 * 123 * @return string The formatted log lin 124 */ 125 protected function formatLogLine($log_line) 126 { 127 static $constants; 128 129 if (!$constants) 130 { 131 foreach (array('sf_app_dir', 'sf_root_dir', 'sf_symfony_lib_dir', 'sf_symfony_data_dir') as $constant) 132 { 133 $constants[realpath(sfConfig::get($constant)).DIRECTORY_SEPARATOR] = $constant.DIRECTORY_SEPARATOR; 134 } 135 } 136 137 // escape HTML 138 $log_line = htmlentities($log_line, ENT_QUOTES, sfConfig::get('sf_charset')); 139 140 // replace constants value with constant name 141 $log_line = str_replace(array_keys($constants), array_values($constants), $log_line); 142 143 $log_line = sfToolkit::pregtr($log_line, array('/"(.+?)"/s' => '"<span class="sfWebDebugLogInfo">\\1</span>"', 144 '/^(.+?)\(\)\:/S' => '<span class="sfWebDebugLogInfo">\\1()</span>:', 145 '/line (\d+)$/' => 'line <span class="sfWebDebugLogInfo">\\1</span>')); 146 147 // special formatting for SQL lines 148 $log_line = preg_replace('/\b(SELECT|FROM|AS|LIMIT|ASC|COUNT|DESC|WHERE|LEFT JOIN|INNER JOIN|RIGHT JOIN|ORDER BY|GROUP BY|IN|LIKE|DISTINCT|DELETE|INSERT|INTO|VALUES)\b/', '<span class="sfWebDebugLogInfo">\\1</span>', $log_line); 149 150 // remove username/password from DSN 151 if (strpos($log_line, 'DSN') !== false) 152 { 153 $log_line = preg_replace("/=>\s+'?[^'\s,]+'?/", "=> '****'", $log_line); 154 } 155 156 return $log_line; 157 } 158 159 /** 160 * Returns the web debug toolbar as HTML. 161 * 162 * @return string The web debug toolbar HTML 163 */ 164 public function getResults() 165 { 166 if (!sfConfig::get('sf_web_debug')) 167 { 168 return ''; 169 } 170 171 $this->loadHelpers(); 172 173 $result = ''; 174 175 // max priority 176 $max_priority = ''; 177 if (sfConfig::get('sf_logging_enabled')) 178 { 179 $max_priority = $this->getPriority($this->max_priority); 180 } 181 182 $logs = ''; 183 $sql_logs = array(); 184 if (sfConfig::get('sf_logging_enabled')) 185 { 186 $logs = '<table class="sfWebDebugLogs"> 187 <tr> 188 <th>#</th> 189 <th>type</th> 190 <th>message</th> 191 </tr>'."\n"; 192 $line_nb = 0; 193 foreach ($this->log as $logEntry) 194 { 195 $log = $logEntry['message']; 196 197 $priority = $this->getPriority($logEntry['priority']); 198 199 if (strpos($type = $logEntry['type'], 'sf') === 0) 200 { 201 $type = substr($type, 2); 202 } 203 204 // xdebug information 205 $debug_info = ''; 206 if ($logEntry['debugStack']) 207 { 208 $debug_info .= ' <a href="#" onclick="sfWebDebugToggle(\'debug_'.$line_nb.'\'); return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/toggle.gif').'</a><div class="sfWebDebugDebugInfo" id="debug_'.$line_nb.'" style="display:none">'; 209 foreach ($logEntry['debugStack'] as $i => $log_line) 210 { 211 $debug_info .= '#'.$i.' » '.$this->formatLogLine($log_line).'<br/>'; 212 } 213 $debug_info .= "</div>\n"; 214 } 215 216 // format log 217 $log = $this->formatLogLine($log); 218 219 // sql queries log 220 if (preg_match('/execute(?:Query|Update).+?\:\s+(.+)$/', $log, $match)) 221 { 222 $sql_logs[] .= $match[1]; 223 } 224 225 ++$line_nb; 226 $logs .= sprintf("<tr class='sfWebDebugLogLine sfWebDebug%s %s'><td class=\"sfWebDebugLogNumber\">%s</td><td class=\"sfWebDebugLogType\">%s %s</td><td>%s%s</td></tr>\n", 227 ucfirst($priority), 228 $logEntry['type'], 229 $line_nb, 230 image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/'.$priority.'.png'), 231 $type, 232 $log, 233 $debug_info 234 ); 235 } 236 $logs .= '</table>'; 237 238 ksort($this->types); 239 $types = array(); 240 foreach ($this->types as $type => $nb) 241 { 242 $types[] = '<a href="#" onclick="sfWebDebugToggleMessages(\''.$type.'\'); return false;">'.$type.'</a>'; 243 } 244 } 245 246 // ignore cache link 247 $cacheLink = ''; 248 if (sfConfig::get('sf_debug') && sfConfig::get('sf_cache')) 249 { 250 $self_url = $_SERVER['PHP_SELF'].((strpos($_SERVER['PHP_SELF'], '_sf_ignore_cache') === false) ? '?_sf_ignore_cache=1' : ''); 251 $cacheLink = '<li><a href="'.$self_url.'" title="reload and ignore cache">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/reload.png').'</a></li>'; 252 } 253 254 // logging information 255 $logLink = ''; 256 if (sfConfig::get('sf_logging_enabled')) 257 { 258 $logLink = '<li><a href="#" onclick="sfWebDebugShowDetailsFor(\'sfWebDebugLog\'); return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/comment.png').' logs & msgs</a></li>'; 259 } 260 261 // database information 262 $dbInfo = ''; 263 $dbInfoDetails = ''; 264 if ($sql_logs) 265 { 266 $dbInfo = '<li><a href="#" onclick="sfWebDebugShowDetailsFor(\'sfWebDebugDatabaseDetails\'); return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/database.png').' '.count($sql_logs).'</a></li>'; 267 268 $dbInfoDetails = ' 269 <div id="sfWebDebugDatabaseLogs"> 270 <ol><li>'.implode("</li>\n<li>", $sql_logs).'</li></ol> 271 </div> 272 '; 273 } 274 275 // memory used 276 $memoryInfo = ''; 277 if (sfConfig::get('sf_debug') && function_exists('memory_get_usage')) 278 { 279 $total_memory = sprintf('%.1f', (memory_get_usage() / 1024)); 280 $memoryInfo = '<li>'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/memory.png').' '.$total_memory.' KB</li>'; 281 } 282 283 // total time elapsed 284 $timeInfo = ''; 285 if (sfConfig::get('sf_debug')) 286 { 287 $total_time = (microtime(true) - sfConfig::get('sf_timer_start')) * 1000; 288 $total_time = sprintf(($total_time <= 1) ? '%.2f' : '%.0f', $total_time); 289 $timeInfo = '<li class="last"><a href="#" onclick="sfWebDebugShowDetailsFor(\'sfWebDebugTimeDetails\'); return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/time.png').' '.$total_time.' ms</a></li>'; 290 } 291 292 // timers 293 $timeInfoDetails = '<table class="sfWebDebugLogs" style="width: 300px"><tr><th>type</th><th>calls</th><th>time (ms)</th></tr>'; 294 foreach (sfTimerManager::getTimers() as $name => $timer) 295 { 296 $timeInfoDetails .= sprintf('<tr><td class="sfWebDebugLogType">%s</td><td class="sfWebDebugLogNumber" style="text-align: right">%d</td><td style="text-align: right">%.2f</td></tr>', $name, $timer->getCalls(), $timer->getElapsedTime() * 1000); 297 } 298 $timeInfoDetails .= '</table>'; 299 300 // short log messages 301 $short_messages = ''; 302 if ($this->short_log) 303 { 304 $short_messages = '<ul id="sfWebDebugShortMessages"><li>» '.implode('</li><li>» ', $this->short_log).'</li></ul>'; 305 } 306 307 // logs 308 $logInfo = ''; 309 if (sfConfig::get('sf_logging_enabled')) 310 { 311 $logInfo .= $short_messages.' 312 <ul id="sfWebDebugLogMenu"> 313 <li><a href="#" onclick="sfWebDebugToggleAllLogLines(true, \'sfWebDebugLogLine\'); return false;">[all]</a></li> 314 <li><a href="#" onclick="sfWebDebugToggleAllLogLines(false, \'sfWebDebugLogLine\'); return false;">[none]</a></li> 315 <li><a href="#" onclick="sfWebDebugShowOnlyLogLines(\'info\'); return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/info.png').'</a></li> 316 <li><a href="#" onclick="sfWebDebugShowOnlyLogLines(\'warning\'); return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/warning.png').'</a></li> 317 <li><a href="#" onclick="sfWebDebugShowOnlyLogLines(\'error\'); return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/error.png').'</a></li> 318 <li>'.implode("</li>\n<li>", $types).'</li> 319 </ul> 320 <div id="sfWebDebugLogLines">'.$logs.'</div> 321 '; 322 } 323 324 $result .= ' 325 <div id="sfWebDebug"> 326 <div id="sfWebDebugBar" class="sfWebDebug'.ucfirst($max_priority).'"> 327 <a href="#" onclick="sfWebDebugToggleMenu(); return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/sf.png').'</a> 328 <ul id="sfWebDebugDetails" class="menu"> 329 <li>'.file_get_contents(sfConfig::get('sf_symfony_lib_dir').'/VERSION').'</li> 330 <li><a href="#" onclick="sfWebDebugShowDetailsFor(\'sfWebDebugConfig\'); return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/config.png').' vars & config</a></li> 331 '.$cacheLink.' 332 '.$logLink.' 333 '.$dbInfo.' 334 '.$memoryInfo.' 335 '.$timeInfo.' 336 </ul> 337 <a href="#" onclick="document.getElementById(\'sfWebDebug\').style.display=\'none\'; return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/close.png').'</a> 338 </div> 339 340 <div id="sfWebDebugLog" class="top" style="display: none"><h1>Log and debug messages</h1>'.$logInfo.'</div> 341 <div id="sfWebDebugConfig" class="top" style="display: none"><h1>Configuration and request variables</h1>'.$this->getCurrentConfigAsHtml().'</div> 342 <div id="sfWebDebugDatabaseDetails" class="top" style="display: none"><h1>SQL queries</h1>'.$dbInfoDetails.'</div> 343 <div id="sfWebDebugTimeDetails" class="top" style="display: none"><h1>Timers</h1>'.$timeInfoDetails.'</div> 344 345 </div> 346 '; 347 348 return $result; 349 } 350 351 /** 352 * Returns the current configuration as HTML. 353 * 354 * @return string The current configuration as HTML 355 */ 356 protected function getCurrentConfigAsHtml() 357 { 358 $config = array( 359 'debug' => sfConfig::get('sf_debug') ? 'on' : 'off', 360 'xdebug' => (extension_loaded('xdebug')) ? 'on' : 'off', 361 'logging' => sfConfig::get('sf_logging_enabled') ? 'on' : 'off', 362 'cache' => sfConfig::get('sf_cache') ? 'on' : 'off', 363 'eaccelerator' => (extension_loaded('eaccelerator') && ini_get('eaccelerator.enable')) ? 'on' : 'off', 364 'apc' => (extension_loaded('apc') && ini_get('apc.enabled')) ? 'on' : 'off', 365 'xcache' => (extension_loaded('xcache') && ini_get('xcache.cacher')) ? 'on' : 'off', 366 'compression' => sfConfig::get('sf_compressed') ? 'on' : 'off', 367 'syck' => (extension_loaded('syck')) ? 'on' : 'off', 368 ); 369 370 $result = '<ul id="sfWebDebugConfigSummary">'; 371 foreach ($config as $key => $value) 372 { 373 $result .= '<li class="is'.$value.''.($key == 'syck' ? ' last' : '').'">'.$key.'</li>'; 374 } 375 $result .= '</ul>'; 376 377 $context = sfContext::getInstance(); 378 $result .= $this->formatArrayAsHtml('request', sfDebug::requestAsArray($context->getRequest())); 379 $result .= $this->formatArrayAsHtml('response', sfDebug::responseAsArray($context->getResponse())); 380 $result .= $this->formatArrayAsHtml('settings', sfDebug::settingsAsArray()); 381 $result .= $this->formatArrayAsHtml('globals', sfDebug::globalsAsArray()); 382 $result .= $this->formatArrayAsHtml('php', sfDebug::phpInfoAsArray()); 383 384 return $result; 385 } 386 387 /** 388 * Converts an array to HTML. 389 * 390 * @param string The identifier to use 391 * @param array The array of values 392 * 393 * @return string An HTML string 394 */ 395 protected function formatArrayAsHtml($id, $values) 396 { 397 $id = ucfirst(strtolower($id)); 398 $content = ' 399 <h2>'.$id.' <a href="#" onclick="sfWebDebugToggle(\'sfWebDebug'.$id.'\'); return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/toggle.gif').'</a></h2> 400 <div id="sfWebDebug'.$id.'" style="display: none"><pre>'.htmlentities(@sfYaml::Dump($values), ENT_QUOTES, sfConfig::get('sf_charset')).'</pre></div> 401 '; 402 403 return $content; 404 } 405 406 /** 407 * Decorates a chunk of HTML with cache information. 408 * 409 * @param string The internalUri representing the content 410 * @param string The HTML content 411 * @param boolean true if the content is new in the cache, false otherwise 412 * 413 * @return string The decorated HTML string 414 */ 415 public function decorateContentWithDebug($internalUri, $content, $new = false) 416 { 417 $context = sfContext::getInstance(); 418 419 // don't decorate if not html or if content is null 420 if (!sfConfig::get('sf_web_debug') || !$content || false === strpos($context->getResponse()->getContentType(), 'html')) 421 { 422 return $content; 423 } 424 425 $cache = $context->getViewCacheManager(); 426 $this->loadHelpers(); 427 428 $bg_color = $new ? '#9ff' : '#ff9'; 429 $last_modified = $cache->lastModified($internalUri); 430 $id = md5($internalUri); 431 $content = ' 432 <div id="main_'.$id.'" class="sfWebDebugActionCache" style="border: 1px solid #f00"> 433 <div id="sub_main_'.$id.'" class="sfWebDebugCache" style="background-color: '.$bg_color.'; border-right: 1px solid #f00; border-bottom: 1px solid #f00;"> 434 <div style="height: 16px; padding: 2px"><a href="#" onclick="sfWebDebugToggle(\''.$id.'\'); return false;"><strong>cache information</strong></a> <a href="#" onclick="sfWebDebugToggle(\'sub_main_'.$id.'\'); document.getElementById(\'main_'.$id.'\').style.border = \'none\'; return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/close.png').'</a> </div> 435 <div style="padding: 2px; display: none" id="'.$id.'"> 436 [uri] '.$internalUri.'<br /> 437 [life time] '.$cache->getLifeTime($internalUri).' seconds<br /> 438 [last modified] '.(time() - $last_modified).' seconds<br /> 439 <br /> 440 </div> 441 </div><div> 442 '.$content.' 443 </div></div> 444 '; 445 446 return $content; 447 } 448 449 /** 450 * Converts a proprity value to a string. 451 * 452 * @param integer The priority value 453 * 454 * @return string The priority as a string 455 */ 456 protected function getPriority($value) 457 { 458 if ($value >= 6) 459 { 460 return 'info'; 461 } 462 else if ($value >= 4) 463 { 464 return 'warning'; 465 } 466 else 467 { 468 return 'error'; 469 } 470 } 471 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |