PageRenderTime 44ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/typo3/class.t3lib_utility_debug.php

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