[TASK] Use CLI and Composer Checks via Environment class
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Utility / DebugUtility.php
1 <?php
2 namespace TYPO3\CMS\Core\Utility;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Core\Environment;
18 use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
19
20 /**
21 * Class to handle debug
22 */
23 class DebugUtility
24 {
25 /**
26 * @var bool
27 */
28 protected static $plainTextOutput = true;
29
30 /**
31 * @var bool
32 */
33 protected static $ansiColorUsage = true;
34
35 /**
36 * Debug
37 *
38 * Directly echos out debug information as HTML (or plain in CLI context)
39 *
40 * @param string $var
41 * @param string $header
42 * @param string $group
43 */
44 public static function debug($var = '', $header = 'Debug', $group = 'Debug')
45 {
46 // buffer the output of debug if no buffering started before
47 if (ob_get_level() === 0) {
48 ob_start();
49 }
50
51 if (TYPO3_MODE === 'BE' && !Environment::isCli()) {
52 $debug = self::renderDump($var);
53 $debugPlain = PHP_EOL . self::renderDump($var, '', true, false);
54 $script = '
55 (function debug() {
56 var message = ' . GeneralUtility::quoteJSvalue($debug) . ',
57 messagePlain = ' . GeneralUtility::quoteJSvalue($debugPlain) . ',
58 header = ' . GeneralUtility::quoteJSvalue($header) . ',
59 group = ' . GeneralUtility::quoteJSvalue($group) . ';
60 if (top.TYPO3 && top.TYPO3.DebugConsole) {
61 top.TYPO3.DebugConsole.add(message, header, group);
62 } else {
63 var consoleMessage = [group, header, messagePlain].join(" | ");
64 if (typeof console === "object" && typeof console.log === "function") {
65 console.log(consoleMessage);
66 }
67 };
68 })();
69 ';
70 echo GeneralUtility::wrapJS($script);
71 } else {
72 echo self::renderDump($var, $header);
73 }
74 }
75
76 /**
77 * Converts a variable to a string
78 *
79 * @param mixed $variable
80 * @return string plain, not HTML encoded string
81 */
82 public static function convertVariableToString($variable)
83 {
84 $string = self::renderDump($variable, '', true, false);
85 return $string === '' ? '| debug |' : $string;
86 }
87
88 /**
89 * Opens a debug message inside a popup window
90 *
91 * @param mixed $debugVariable
92 * @param string $header
93 * @param string $group
94 */
95 public static function debugInPopUpWindow($debugVariable, $header = 'Debug', $group = 'Debug')
96 {
97 $debugString = self::renderDump($debugVariable, sprintf('%s (%s)', $header, $group));
98 $script = '
99 (function debug() {
100 var debugMessage = ' . GeneralUtility::quoteJSvalue($debugString) . ',
101 header = ' . GeneralUtility::quoteJSvalue($header) . ',
102 group = ' . GeneralUtility::quoteJSvalue($group) . ',
103
104 browserWindow = function(debug, header, group) {
105 var newWindow = window.open("", "TYPO3DebugWindow_" + group,
106 "width=600,height=400,menubar=0,toolbar=1,status=0,scrollbars=1,resizable=1"
107 );
108 if (newWindow.document.body.innerHTML) {
109 newWindow.document.body.innerHTML = newWindow.document.body.innerHTML +
110 "<hr />" + debugMessage;
111 } else {
112 newWindow.document.writeln(
113 "<html><head><title>Debug: " + header + "(" + group + ")</title></head>"
114 + "<body onload=\\"self.focus()\\">"
115 + debugMessage
116 + "</body></html>"
117 );
118 }
119 };
120
121 if (top && typeof top.TYPO3 !== "undefined" && typeof top.TYPO3.Modal !== "undefined") {
122 top.TYPO3.Modal.show(
123 "Debug: " + header + " (" + group + ")",
124 debugMessage,
125 top.TYPO3.Severity.notice
126 );
127 } else {
128 browserWindow(debugMessage, header, group);
129 }
130 })();
131 ';
132 echo GeneralUtility::wrapJS($script);
133 }
134
135 /**
136 * Displays the "path" of the function call stack in a string, using debug_backtrace
137 *
138 * @param bool $prependFileNames If set to true file names are added to the output
139 * @return string plain, not HTML encoded string
140 */
141 public static function debugTrail($prependFileNames = false)
142 {
143 $trail = debug_backtrace(0);
144 $trail = array_reverse($trail);
145 array_pop($trail);
146 $path = [];
147 foreach ($trail as $dat) {
148 $fileInformation = $prependFileNames && !empty($dat['file']) ? $dat['file'] . ':' : '';
149 $pathFragment = $fileInformation . $dat['class'] . $dat['type'] . $dat['function'];
150 // add the path of the included file
151 if (in_array($dat['function'], ['require', 'include', 'require_once', 'include_once'])) {
152 $pathFragment .= '(' . PathUtility::stripPathSitePrefix($dat['args'][0]) . '),' . PathUtility::stripPathSitePrefix($dat['file']);
153 }
154 $path[] = $pathFragment . '#' . $dat['line'];
155 }
156 return implode(' // ', $path);
157 }
158
159 /**
160 * Displays an array as rows in a table. Useful to debug output like an array of database records.
161 *
162 * @param mixed $rows Array of arrays with similar keys
163 * @param string $header Table header
164 */
165 public static function debugRows($rows, $header = '')
166 {
167 self::debug($rows, $header);
168 }
169
170 /**
171 * Returns a string with a list of ascii-values for the first $characters characters in $string
172 *
173 * @param string $string String to show ASCII value for
174 * @param int $characters Number of characters to show
175 * @return string The string with ASCII values in separated by a space char.
176 */
177 public static function ordinalValue($string, $characters = 100)
178 {
179 if (strlen($string) < $characters) {
180 $characters = strlen($string);
181 }
182 $valuestring = '';
183 for ($i = 0; $i < $characters; $i++) {
184 $valuestring .= ' ' . ord(substr($string, $i, 1));
185 }
186 return trim($valuestring);
187 }
188
189 /**
190 * Returns HTML-code, which is a visual representation of a multidimensional array
191 * use \TYPO3\CMS\Core\Utility\GeneralUtility::print_array() in order to print an array
192 * Returns FALSE if $array_in is not an array
193 *
194 * @param mixed $array_in Array to view
195 * @return string HTML output
196 */
197 public static function viewArray($array_in)
198 {
199 return self::renderDump($array_in);
200 }
201
202 /**
203 * Prints an array
204 *
205 * @param mixed $array_in Array to print visually (in a table).
206 * @see viewArray()
207 */
208 public static function printArray($array_in)
209 {
210 echo self::renderDump($array_in);
211 }
212
213 /**
214 * Renders the dump according to the context, either for command line or as HTML output
215 *
216 * @param mixed $variable
217 * @param string $title
218 * @param bool|null $plainText
219 * @param bool|null $ansiColors
220 * @return string
221 */
222 protected static function renderDump($variable, $title = '', $plainText = null, $ansiColors = null)
223 {
224 $plainText = $plainText ?? Environment::isCli() && self::$plainTextOutput;
225 $ansiColors = $ansiColors ?? Environment::isCli() && self::$ansiColorUsage;
226 return trim(DebuggerUtility::var_dump($variable, $title, 8, $plainText, $ansiColors, true));
227 }
228
229 /**
230 * Preset plaintext output
231 *
232 * Warning:
233 * This is NOT a public API method and must not be used in own extensions!
234 * This method is usually only used in tests to preset the output behaviour
235 *
236 * @internal
237 * @param bool $plainTextOutput
238 */
239 public static function usePlainTextOutput($plainTextOutput)
240 {
241 static::$plainTextOutput = $plainTextOutput;
242 }
243
244 /**
245 * Preset ansi color usage
246 *
247 * Warning:
248 * This is NOT a public API method and must not be used in own extensions!
249 * This method is usually only used in tests to preset the ansi color usage
250 *
251 * @internal
252 * @param bool $ansiColorUsage
253 */
254 public static function useAnsiColor($ansiColorUsage)
255 {
256 static::$ansiColorUsage = $ansiColorUsage;
257 }
258 }