TYPO3 API  SVNRelease
class.t3lib_utility_debug.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  * Copyright notice
00004  *
00005  * (c) 2010-2011 Steffen Kamper <steffen@typo3.org>
00006  * All rights reserved
00007  *
00008  * This script is part of the TYPO3 project. The TYPO3 project is
00009  * free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * The GNU General Public License can be found at
00015  * http://www.gnu.org/copyleft/gpl.html.
00016  * A copy is found in the textfile GPL.txt and important notices to the license
00017  * from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  * This script is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  *
00025  * This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00027 
00028 /**
00029  * Class to handle debug
00030  *
00031  * $Id: $
00032  *
00033  *
00034  * @author   Steffen Kamper <steffen@typo3.org>
00035  * @package TYPO3
00036  * @subpackage t3lib
00037  */
00038 final class t3lib_utility_Debug {
00039 
00040     /**
00041      * Template for debug output
00042      *
00043      * @var string
00044      */
00045     const DEBUG_TABLE_TEMPLATE = '
00046     <table class="typo3-debug" border="0" cellpadding="0" cellspacing="0" bgcolor="white" style="border:0px; margin-top:3px; margin-bottom:3px;">
00047         <tr>
00048             <td style="background-color:#bbbbbb; font-family: verdana,arial; font-weight: bold; font-size: 10px;">%s</td>
00049         </tr>
00050         <tr>
00051             <td>
00052             %s
00053             </td>
00054         </tr>
00055     </table>
00056     ';
00057 
00058 
00059     public static function debug($var = '', $header = '', $group = 'Debug') {
00060             // buffer the output of debug if no buffering started before
00061         if (ob_get_level() == 0) {
00062             ob_start();
00063         }
00064 
00065         $debug = self::convertVariableToString($var);
00066         if ($header) {
00067             $debug = sprintf(self::DEBUG_TABLE_TEMPLATE, htmlspecialchars((string) $header), $debug);
00068         }
00069 
00070         if (TYPO3_MODE === 'BE') {
00071             $debugString = self::prepareVariableForJavascript($debug, is_object($var));
00072             $group = htmlspecialchars($group);
00073 
00074             if ($header !== '') {
00075                 $tabHeader = htmlspecialchars($header);
00076             } else {
00077                 $tabHeader = 'Debug';
00078             }
00079 
00080             $script = '
00081                 (function debug() {
00082                     var debugMessage = "' . $debugString . '";
00083                     var header = "' . $tabHeader . '";
00084                     var group = "' . $group . '";
00085 
00086                     if (typeof Ext !== "object" && (top && typeof top.Ext !== "object")) {
00087                         document.write(debugMessage);
00088                         return;
00089                     }
00090 
00091                     if (top && typeof Ext !== "object") {
00092                         Ext = top.Ext;
00093                     }
00094 
00095                     Ext.onReady(function() {
00096                         var TYPO3ViewportInstance = null;
00097 
00098                         if (top && top.TYPO3 && typeof top.TYPO3.Backend === "object") {
00099                             TYPO3ViewportInstance = top.TYPO3.Backend;
00100                         } else if (typeof TYPO3 === "object" && typeof TYPO3.Backend === "object") {
00101                             TYPO3ViewportInstance = TYPO3.Backend;
00102                         }
00103 
00104                         if (TYPO3ViewportInstance !== null) {
00105                             TYPO3ViewportInstance.DebugConsole.addTab(debugMessage, header, group);
00106                         } else {
00107                             document.write(debugMessage);
00108                         }
00109                     });
00110                 })();
00111             ';
00112             echo t3lib_div::wrapJS($script);
00113         } else {
00114             echo $debug;
00115         }
00116     }
00117 
00118     /**
00119      * Replaces special characters for the usage inside javascript
00120      *
00121      * @param string $string
00122      * @param boolean $asObject
00123      * @return string
00124      */
00125     public static function prepareVariableForJavascript($string, $asObject) {
00126         if ($asObject) {
00127             $string = str_replace(array(
00128                 '"', '/', '<', "\n", "\r"
00129             ), array(
00130                 '\"', '\/', '<', '<br />', ''
00131             ), $string);
00132         } else {
00133             $string = str_replace(array(
00134                 '"', '/', '<', "\n", "\r"
00135           ), array(
00136                 '\"', '\/', '<', '', ''
00137             ), $string);
00138         }
00139 
00140         return $string;
00141     }
00142 
00143     /**
00144      * Converts a variable to a string
00145      *
00146      * @param mixed $variable
00147      * @return string
00148      */
00149     public static function convertVariableToString($variable) {
00150         $string = '';
00151         if (is_array($variable)) {
00152             $string = self::viewArray($variable);
00153         } elseif (is_object($variable)) {
00154             $string = '<strong>|Object:<pre>';
00155             $string .= print_r($variable, TRUE);
00156             $string .= '</pre>|</strong>';
00157         } elseif ((string) $variable !== '') {
00158             $string = '<strong>|' . htmlspecialchars((string) $variable) . '|</strong>';
00159         } else {
00160             $string = '<strong>| debug |</strong>';
00161         }
00162 
00163         return $string;
00164     }
00165 
00166     /**
00167      * Opens a debug message inside a popup window
00168      *
00169      * @param mixed $debugVariable
00170      * @param string $header
00171      * @param string $group
00172      */
00173     public static function debugInPopUpWindow($debugVariable, $header = 'Debug', $group = 'Debug') {
00174         $debugString = self::prepareVariableForJavascript(
00175             self::convertVariableToString($debugVariable),
00176             is_object($debugVariable)
00177         );
00178 
00179         $script = '
00180             (function debug() {
00181                 var debugMessage = "' . $debugString . '",
00182                     header = "' . htmlspecialchars($header) . '",
00183                     group = "' . htmlspecialchars($group) . '",
00184 
00185                     browserWindow = function(debug, header, group) {
00186                         var newWindow = window.open("", "TYPO3DebugWindow_" + group,
00187                             "width=600,height=400,menubar=0,toolbar=1,status=0,scrollbars=1,resizable=1"
00188                         );
00189                         if (newWindow.document.body.innerHTML) {
00190                             newWindow.document.body.innerHTML = newWindow.document.body.innerHTML +
00191                                 "<hr />" + debugMessage;
00192                         } else {
00193                             newWindow.document.writeln(
00194                                 "<html><head><title>Debug: " + header + "(" + group + ")</title></head>"
00195                                 + "<body onload=\"self.focus()\">"
00196                                 + debugMessage
00197                                 + "</body></html>"
00198                             );
00199                         }
00200                     }
00201 
00202                 if (!top.Ext) {
00203                     browserWindow(debugMessage, header, group);
00204                 } else {
00205                     top.Ext.onReady(function() {
00206                         if (top && top.TYPO3 && top.TYPO3.Backend) {
00207                             top.TYPO3.Backend.DebugConsole.openBrowserWindow(header, debugMessage, group);
00208                         } else {
00209                             browserWindow(debugMessage, header, group);
00210                         }
00211                     });
00212                 }
00213             })();
00214         ';
00215         echo t3lib_div::wrapJS($script);
00216     }
00217 
00218     /**
00219      * Displays the "path" of the function call stack in a string, using debug_backtrace
00220      *
00221      * @return  string
00222      */
00223     public static function debugTrail() {
00224         $trail = debug_backtrace();
00225         $trail = array_reverse($trail);
00226         array_pop($trail);
00227 
00228         $path = array();
00229         foreach ($trail as $dat) {
00230             $path[] = $dat['class'] . $dat['type'] . $dat['function'] . '#' . $dat['line'];
00231         }
00232 
00233         return implode(' // ', $path);
00234     }
00235 
00236     /**
00237      * Displays an array as rows in a table. Useful to debug output like an array of database records.
00238      *
00239      * @param   mixed       Array of arrays with similar keys
00240      * @param   string      Table header
00241      * @param   boolean     If TRUE, will return content instead of echo'ing out.
00242      * @return  void        Outputs to browser.
00243      */
00244     public static function debugRows($rows, $header = '', $returnHTML = FALSE) {
00245         if (is_array($rows)) {
00246             reset($rows);
00247             $firstEl = current($rows);
00248             if (is_array($firstEl)) {
00249                 $headerColumns = array_keys($firstEl);
00250                 $tRows = array();
00251 
00252                     // Header:
00253                 $tRows[] = '<tr><td colspan="' . count($headerColumns) .
00254                            '" style="background-color:#bbbbbb; font-family: verdana,arial; font-weight: bold; font-size: 10px;"><strong>' .
00255                            htmlspecialchars($header) . '</strong></td></tr>';
00256                 $tCells = array();
00257                 foreach ($headerColumns as $key) {
00258                     $tCells[] = '
00259                             <td><font face="Verdana,Arial" size="1"><strong>' . htmlspecialchars($key) . '</strong></font></td>';
00260                 }
00261                 $tRows[] = '
00262                         <tr>' . implode('', $tCells) . '
00263                         </tr>';
00264 
00265                     // Rows:
00266                 foreach ($rows as $singleRow) {
00267                     $tCells = array();
00268                     foreach ($headerColumns as $key) {
00269                         $tCells[] = '
00270                             <td><font face="Verdana,Arial" size="1">' .
00271                                     (is_array($singleRow[$key]) ? self::debugRows($singleRow[$key], '', TRUE) : htmlspecialchars($singleRow[$key])) .
00272                                     '</font></td>';
00273                     }
00274                     $tRows[] = '
00275                         <tr>' . implode('', $tCells) . '
00276                         </tr>';
00277                 }
00278 
00279                 $table = '
00280                     <table border="1" cellpadding="1" cellspacing="0" bgcolor="white">' . implode('', $tRows) . '
00281                     </table>';
00282                 if ($returnHTML) {
00283                     return $table;
00284                 }
00285                 else
00286                 {
00287                     echo $table;
00288                 }
00289             } else
00290             {
00291                 debug('Empty array of rows', $header);
00292             }
00293         } else {
00294             debug('No array of rows', $header);
00295         }
00296     }
00297 
00298     /**
00299      * Returns a string with a list of ascii-values for the first $characters characters in $string
00300      *
00301      * @param   string      String to show ASCII value for
00302      * @param   integer     Number of characters to show
00303      * @return  string      The string with ASCII values in separated by a space char.
00304      */
00305     public static function ordinalValue($string, $characters = 100) {
00306         if (strlen($string) < $characters) {
00307             $characters = strlen($string);
00308         }
00309         for ($i = 0; $i < $characters; $i++) {
00310             $valuestring .= ' ' . ord(substr($string, $i, 1));
00311         }
00312         return trim($valuestring);
00313     }
00314 
00315     /**
00316      * Returns HTML-code, which is a visual representation of a multidimensional array
00317      * use t3lib_div::print_array() in order to print an array
00318      * Returns false if $array_in is not an array
00319      *
00320      * @param   mixed       Array to view
00321      * @return  string      HTML output
00322      */
00323     public static function viewArray($array_in) {
00324         if (is_array($array_in)) {
00325             $result = '
00326             <table border="1" cellpadding="1" cellspacing="0" bgcolor="white">';
00327             if (count($array_in) == 0) {
00328                 $result .= '<tr><td><font face="Verdana,Arial" size="1"><strong>EMPTY!</strong></font></td></tr>';
00329             } else {
00330                 foreach ($array_in as $key => $val) {
00331                     $result .= '<tr>
00332                         <td valign="top"><font face="Verdana,Arial" size="1">' . htmlspecialchars((string) $key) . '</font></td>
00333                         <td>';
00334                     if (is_array($val)) {
00335                         $result .= self::viewArray($val);
00336                     } elseif (is_object($val)) {
00337                         $string = '';
00338                         if (method_exists($val, '__toString')) {
00339                             $string .= get_class($val) . ': ' . (string) $val;
00340                         } else {
00341                             $string .= print_r($val, TRUE);
00342                         }
00343                         $result .= '<font face="Verdana,Arial" size="1" color="red">' .
00344                                    nl2br(htmlspecialchars($string)) .
00345                                    '<br /></font>';
00346                     } else {
00347                         if (gettype($val) == 'object') {
00348                             $string = 'Unknown object';
00349                         } else {
00350                             $string = (string) $val;
00351                         }
00352                         $result .= '<font face="Verdana,Arial" size="1" color="red">' .
00353                                    nl2br(htmlspecialchars($string)) .
00354                                    '<br /></font>';
00355                     }
00356                     $result .= '</td>
00357                     </tr>';
00358                 }
00359             }
00360             $result .= '</table>';
00361         } else {
00362             $result = '<table border="1" cellpadding="1" cellspacing="0" bgcolor="white">
00363                 <tr>
00364                     <td><font face="Verdana,Arial" size="1" color="red">' .
00365                       nl2br(htmlspecialchars((string) $array_in)) .
00366                       '<br /></font></td>
00367                 </tr>
00368             </table>'; // Output it as a string.
00369         }
00370         return $result;
00371     }
00372 
00373     /**
00374      * Prints an array
00375      *
00376      * @param   mixed       Array to print visually (in a table).
00377      * @return  void
00378      * @see view_array()
00379      */
00380     public static function printArray($array_in) {
00381         echo self::viewArray($array_in);
00382     }
00383 }
00384 
00385 ?>