1 <?php 2 /*************************************************************** 3 * Copyright notice 4 * 5 * (c) 2010-2011 Steffen Kamper <steffen@typo3.org> 6 * All rights reserved 7 * 8 * This script is part of the TYPO3 project. The TYPO3 project is 9 * free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * The GNU General Public License can be found at 15 * http://www.gnu.org/copyleft/gpl.html. 16 * A copy is found in the textfile GPL.txt and important notices to the license 17 * from the author is found in LICENSE.txt distributed with these scripts. 18 * 19 * 20 * This script is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * GNU General Public License for more details. 24 * 25 * This copyright notice MUST APPEAR in all copies of the script! 26 ***************************************************************/ 27 28 /** 29 * Class to handle debug 30 * 31 * 32 * @author Steffen Kamper <steffen@typo3.org> 33 * @package TYPO3 34 * @subpackage t3lib 35 */ 36 final class t3lib_utility_Debug { 37 38 /** 39 * Template for debug output 40 * 41 * @var string 42 */ 43 const DEBUG_TABLE_TEMPLATE = ' 44 <table class="typo3-debug" border="0" cellpadding="0" cellspacing="0" bgcolor="white" style="border:0px; margin-top:3px; margin-bottom:3px;"> 45 <tr> 46 <td style="background-color:#bbbbbb; font-family: verdana,arial; font-weight: bold; font-size: 10px;">%s</td> 47 </tr> 48 <tr> 49 <td> 50 %s 51 </td> 52 </tr> 53 </table> 54 '; 55 56 57 public static function debug($var = '', $header = '', $group = 'Debug') { 58 // buffer the output of debug if no buffering started before 59 if (ob_get_level() == 0) { 60 ob_start(); 61 } 62 63 $debug = self::convertVariableToString($var); 64 if ($header) { 65 $debug = sprintf(self::DEBUG_TABLE_TEMPLATE, htmlspecialchars((string) $header), $debug); 66 } 67 68 if (TYPO3_MODE === 'BE') { 69 $debugString = self::prepareVariableForJavascript($debug, is_object($var)); 70 $group = htmlspecialchars($group); 71 72 if ($header !== '') { 73 $tabHeader = htmlspecialchars($header); 74 } else { 75 $tabHeader = 'Debug'; 76 } 77 78 $script = ' 79 (function debug() { 80 var debugMessage = "' . $debugString . '"; 81 var header = "' . $tabHeader . '"; 82 var group = "' . $group . '"; 83 84 if (typeof Ext !== "object" && (top && typeof top.Ext !== "object")) { 85 document.write(debugMessage); 86 return; 87 } 88 89 if (top && typeof Ext !== "object") { 90 Ext = top.Ext; 91 } 92 93 Ext.onReady(function() { 94 var TYPO3ViewportInstance = null; 95 96 if (top && top.TYPO3 && typeof top.TYPO3.Backend === "object") { 97 TYPO3ViewportInstance = top.TYPO3.Backend; 98 } else if (typeof TYPO3 === "object" && typeof TYPO3.Backend === "object") { 99 TYPO3ViewportInstance = TYPO3.Backend; 100 } 101 102 if (TYPO3ViewportInstance !== null) { 103 TYPO3ViewportInstance.DebugConsole.addTab(debugMessage, header, group); 104 } else { 105 document.write(debugMessage); 106 } 107 }); 108 })(); 109 '; 110 echo t3lib_div::wrapJS($script); 111 } else { 112 echo $debug; 113 } 114 } 115 116 /** 117 * Replaces special characters for the usage inside javascript 118 * 119 * @param string $string 120 * @param boolean $asObject 121 * @return string 122 */ 123 public static function prepareVariableForJavascript($string, $asObject) { 124 if ($asObject) { 125 $string = str_replace(array( 126 '"', '/', '<', "\n", "\r" 127 ), array( 128 '\"', '\/', '\<', '<br />', '' 129 ), $string); 130 } else { 131 $string = str_replace(array( 132 '"', '/', '<', "\n", "\r" 133 ), array( 134 '\"', '\/', '\<', '', '' 135 ), $string); 136 } 137 138 return $string; 139 } 140 141 /** 142 * Converts a variable to a string 143 * 144 * @param mixed $variable 145 * @return string 146 */ 147 public static function convertVariableToString($variable) { 148 $string = ''; 149 if (is_array($variable)) { 150 $string = self::viewArray($variable); 151 } elseif (is_object($variable)) { 152 $string = '<strong>|Object:<pre>'; 153 $string .= print_r($variable, TRUE); 154 $string .= '</pre>|</strong>'; 155 } elseif ((string) $variable !== '') { 156 $string = '<strong>|' . htmlspecialchars((string) $variable) . '|</strong>'; 157 } else { 158 $string = '<strong>| debug |</strong>'; 159 } 160 161 return $string; 162 } 163 164 /** 165 * Opens a debug message inside a popup window 166 * 167 * @param mixed $debugVariable 168 * @param string $header 169 * @param string $group 170 */ 171 public static function debugInPopUpWindow($debugVariable, $header = 'Debug', $group = 'Debug') { 172 $debugString = self::prepareVariableForJavascript( 173 self::convertVariableToString($debugVariable), 174 is_object($debugVariable) 175 ); 176 177 $script = ' 178 (function debug() { 179 var debugMessage = "' . $debugString . '", 180 header = "' . htmlspecialchars($header) . '", 181 group = "' . htmlspecialchars($group) . '", 182 183 browserWindow = function(debug, header, group) { 184 var newWindow = window.open("", "TYPO3DebugWindow_" + group, 185 "width=600,height=400,menubar=0,toolbar=1,status=0,scrollbars=1,resizable=1" 186 ); 187 if (newWindow.document.body.innerHTML) { 188 newWindow.document.body.innerHTML = newWindow.document.body.innerHTML + 189 "<hr />" + debugMessage; 190 } else { 191 newWindow.document.writeln( 192 "<html><head><title>Debug: " + header + "(" + group + ")</title></head>" 193 + "<body onload=\"self.focus()\">" 194 + debugMessage 195 + "</body></html>" 196 ); 197 } 198 } 199 200 if (!top.Ext) { 201 browserWindow(debugMessage, header, group); 202 } else { 203 top.Ext.onReady(function() { 204 if (top && top.TYPO3 && top.TYPO3.Backend) { 205 top.TYPO3.Backend.DebugConsole.openBrowserWindow(header, debugMessage, group); 206 } else { 207 browserWindow(debugMessage, header, group); 208 } 209 }); 210 } 211 })(); 212 '; 213 echo t3lib_div::wrapJS($script); 214 } 215 216 /** 217 * Displays the "path" of the function call stack in a string, using debug_backtrace 218 * 219 * @return string 220 */ 221 public static function debugTrail() { 222 $trail = debug_backtrace(); 223 $trail = array_reverse($trail); 224 array_pop($trail); 225 226 $path = array(); 227 foreach ($trail as $dat) { 228 $pathFragment = $dat['class'] . $dat['type'] . $dat['function']; 229 // add the path of the included file 230 if (in_array($dat['function'], array('require', 'include', 'require_once', 'include_once'))) { 231 $pathFragment .= '(' . substr($dat['args'][0], strlen(PATH_site)) . '),' . substr($dat['file'], strlen(PATH_site)); 232 } 233 $path[] = $pathFragment . '#' . $dat['line']; 234 } 235 236 return implode(' // ', $path); 237 } 238 239 /** 240 * Displays an array as rows in a table. Useful to debug output like an array of database records. 241 * 242 * @param mixed Array of arrays with similar keys 243 * @param string Table header 244 * @param boolean If TRUE, will return content instead of echo'ing out. 245 * @return void Outputs to browser. 246 */ 247 public static function debugRows($rows, $header = '', $returnHTML = FALSE) { 248 if (is_array($rows)) { 249 $firstEl = reset($rows); 250 if (is_array($firstEl)) { 251 $headerColumns = array_keys($firstEl); 252 $tRows = array(); 253 254 // Header: 255 $tRows[] = '<tr><td colspan="' . count($headerColumns) . 256 '" style="background-color:#bbbbbb; font-family: verdana,arial; font-weight: bold; font-size: 10px;"><strong>' . 257 htmlspecialchars($header) . '</strong></td></tr>'; 258 $tCells = array(); 259 foreach ($headerColumns as $key) { 260 $tCells[] = ' 261 <td><font face="Verdana,Arial" size="1"><strong>' . htmlspecialchars($key) . '</strong></font></td>'; 262 } 263 $tRows[] = ' 264 <tr>' . implode('', $tCells) . ' 265 </tr>'; 266 267 // Rows: 268 foreach ($rows as $singleRow) { 269 $tCells = array(); 270 foreach ($headerColumns as $key) { 271 $tCells[] = ' 272 <td><font face="Verdana,Arial" size="1">' . 273 (is_array($singleRow[$key]) ? self::debugRows($singleRow[$key], '', TRUE) : htmlspecialchars($singleRow[$key])) . 274 '</font></td>'; 275 } 276 $tRows[] = ' 277 <tr>' . implode('', $tCells) . ' 278 </tr>'; 279 } 280 281 $table = ' 282 <table border="1" cellpadding="1" cellspacing="0" bgcolor="white">' . implode('', $tRows) . ' 283 </table>'; 284 if ($returnHTML) { 285 return $table; 286 } 287 else 288 { 289 echo $table; 290 } 291 } else 292 { 293 debug('Empty array of rows', $header); 294 } 295 } else { 296 debug('No array of rows', $header); 297 } 298 } 299 300 /** 301 * Returns a string with a list of ascii-values for the first $characters characters in $string 302 * 303 * @param string String to show ASCII value for 304 * @param integer Number of characters to show 305 * @return string The string with ASCII values in separated by a space char. 306 */ 307 public static function ordinalValue($string, $characters = 100) { 308 if (strlen($string) < $characters) { 309 $characters = strlen($string); 310 } 311 for ($i = 0; $i < $characters; $i++) { 312 $valuestring .= ' ' . ord(substr($string, $i, 1)); 313 } 314 return trim($valuestring); 315 } 316 317 /** 318 * Returns HTML-code, which is a visual representation of a multidimensional array 319 * use t3lib_div::print_array() in order to print an array 320 * Returns FALSE if $array_in is not an array 321 * 322 * @param mixed Array to view 323 * @return string HTML output 324 */ 325 public static function viewArray($array_in) { 326 if (is_array($array_in)) { 327 $result = ' 328 <table border="1" cellpadding="1" cellspacing="0" bgcolor="white">'; 329 if (count($array_in) == 0) { 330 $result .= '<tr><td><font face="Verdana,Arial" size="1"><strong>EMPTY!</strong></font></td></tr>'; 331 } else { 332 foreach ($array_in as $key => $val) { 333 $result .= '<tr> 334 <td valign="top"><font face="Verdana,Arial" size="1">' . htmlspecialchars((string) $key) . '</font></td> 335 <td>'; 336 if (is_array($val)) { 337 $result .= self::viewArray($val); 338 } elseif (is_object($val)) { 339 $string = ''; 340 if (method_exists($val, '__toString')) { 341 $string .= get_class($val) . ': ' . (string) $val; 342 } else { 343 $string .= print_r($val, TRUE); 344 } 345 $result .= '<font face="Verdana,Arial" size="1" color="red">' . 346 nl2br(htmlspecialchars($string)) . 347 '<br /></font>'; 348 } else { 349 if (gettype($val) == 'object') { 350 $string = 'Unknown object'; 351 } else { 352 $string = (string) $val; 353 } 354 $result .= '<font face="Verdana,Arial" size="1" color="red">' . 355 nl2br(htmlspecialchars($string)) . 356 '<br /></font>'; 357 } 358 $result .= '</td> 359 </tr>'; 360 } 361 } 362 $result .= '</table>'; 363 } else { 364 $result = '<table border="1" cellpadding="1" cellspacing="0" bgcolor="white"> 365 <tr> 366 <td><font face="Verdana,Arial" size="1" color="red">' . 367 nl2br(htmlspecialchars((string) $array_in)) . 368 '<br /></font></td> 369 </tr> 370 </table>'; // Output it as a string. 371 } 372 return $result; 373 } 374 375 /** 376 * Prints an array 377 * 378 * @param mixed Array to print visually (in a table). 379 * @return void 380 * @see viewArray() 381 */ 382 public static function printArray($array_in) { 383 echo self::viewArray($array_in); 384 } 385 } 386 387 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body