ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
BrowserConsoleHandler.php
Go to the documentation of this file.
1<?php
2
3/*
4 * This file is part of the Monolog package.
5 *
6 * (c) Jordi Boggiano <j.boggiano@seld.be>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Monolog\Handler;
13
15
22{
23 protected static $initialized = false;
24 protected static $records = array();
25
35 protected function getDefaultFormatter()
36 {
37 return new LineFormatter('[[%channel%]]{macro: autolabel} [[%level_name%]]{font-weight: bold} %message%');
38 }
39
43 protected function write(array $record)
44 {
45 // Accumulate records
46 static::$records[] = $record;
47
48 // Register shutdown handler if not already done
49 if (!static::$initialized) {
50 static::$initialized = true;
52 }
53 }
54
59 public static function send()
60 {
61 $format = static::getResponseFormat();
62 if ($format === 'unknown') {
63 return;
64 }
65
66 if (count(static::$records)) {
67 if ($format === 'html') {
68 static::writeOutput('<script>' . static::generateScript() . '</script>');
69 } elseif ($format === 'js') {
70 static::writeOutput(static::generateScript());
71 }
72 static::resetStatic();
73 }
74 }
75
76 public function close()
77 {
79 }
80
81 public function reset()
82 {
84 }
85
89 public static function resetStatic()
90 {
91 static::$records = array();
92 }
93
97 protected function registerShutdownFunction()
98 {
99 if (PHP_SAPI !== 'cli') {
100 register_shutdown_function(array('Monolog\Handler\BrowserConsoleHandler', 'send'));
101 }
102 }
103
109 protected static function writeOutput($str)
110 {
111 echo $str;
112 }
113
123 protected static function getResponseFormat()
124 {
125 // Check content type
126 foreach (headers_list() as $header) {
127 if (stripos($header, 'content-type:') === 0) {
128 // This handler only works with HTML and javascript outputs
129 // text/javascript is obsolete in favour of application/javascript, but still used
130 if (stripos($header, 'application/javascript') !== false || stripos($header, 'text/javascript') !== false) {
131 return 'js';
132 }
133 if (stripos($header, 'text/html') === false) {
134 return 'unknown';
135 }
136 break;
137 }
138 }
139
140 return 'html';
141 }
142
143 private static function generateScript()
144 {
145 $script = array();
146 foreach (static::$records as $record) {
147 $context = static::dump('Context', $record['context']);
148 $extra = static::dump('Extra', $record['extra']);
149
150 if (empty($context) && empty($extra)) {
151 $script[] = static::call_array('log', static::handleStyles($record['formatted']));
152 } else {
153 $script = array_merge($script,
154 array(static::call_array('groupCollapsed', static::handleStyles($record['formatted']))),
155 $context,
156 $extra,
157 array(static::call('groupEnd'))
158 );
159 }
160 }
161
162 return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);";
163 }
164
165 private static function handleStyles($formatted)
166 {
167 $args = array(static::quote('font-weight: normal'));
168 $format = '%c' . $formatted;
169 preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
170
171 foreach (array_reverse($matches) as $match) {
172 $args[] = static::quote(static::handleCustomStyles($match[2][0], $match[1][0]));
173 $args[] = '"font-weight: normal"';
174
175 $pos = $match[0][1];
176 $format = substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . substr($format, $pos + strlen($match[0][0]));
177 }
178
179 array_unshift($args, static::quote($format));
180
181 return $args;
182 }
183
184 private static function handleCustomStyles($style, $string)
185 {
186 static $colors = array('blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey');
187 static $labels = array();
188
189 return preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function ($m) use ($string, &$colors, &$labels) {
190 if (trim($m[1]) === 'autolabel') {
191 // Format the string as a label with consistent auto assigned background color
192 if (!isset($labels[$string])) {
193 $labels[$string] = $colors[count($labels) % count($colors)];
194 }
195 $color = $labels[$string];
196
197 return "background-color: $color; color: white; border-radius: 3px; padding: 0 2px 0 2px";
198 }
199
200 return $m[1];
201 }, $style);
202 }
203
204 private static function dump($title, array $dict)
205 {
206 $script = array();
207 $dict = array_filter($dict);
208 if (empty($dict)) {
209 return $script;
210 }
211 $script[] = static::call('log', static::quote('%c%s'), static::quote('font-weight: bold'), static::quote($title));
212 foreach ($dict as $key => $value) {
213 $value = json_encode($value);
214 if (empty($value)) {
215 $value = static::quote('');
216 }
217 $script[] = static::call('log', static::quote('%s: %o'), static::quote($key), $value);
218 }
219
220 return $script;
221 }
222
223 private static function quote($arg)
224 {
225 return '"' . addcslashes($arg, "\"\n\\") . '"';
226 }
227
228 private static function call()
229 {
230 $args = func_get_args();
231 $method = array_shift($args);
232
233 return static::call_array($method, $args);
234 }
235
236 private static function call_array($method, array $args)
237 {
238 return 'c.' . $method . '(' . implode(', ', $args) . ');';
239 }
240}
An exception for terminatinating execution or to throw for unit testing.
Formats incoming records into a one-line string.
Base Handler class providing the Handler structure.
Handler sending logs to browser's javascript console with no browser extension required.
getDefaultFormatter()
Gets the default formatter.FormatterInterface
registerShutdownFunction()
Wrapper for register_shutdown_function to allow overriding.
static resetStatic()
Forget all logged records.
write(array $record)
Writes the record down to the log of the implementing handler.void
static writeOutput($str)
Wrapper for echo to allow overriding.
static send()
Convert records to javascript console commands and send it to the browser.
static getResponseFormat()
Checks the format of the response.
$key
Definition: croninfo.php:18
$style
Definition: example_012.php:70
$format
Definition: metadata.php:141
$records
Definition: simple_test.php:22
$context
Definition: webdav.php:25