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 
12 namespace 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;
51  $this->registerShutdownFunction();
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  {
78  self::resetStatic();
79  }
80 
81  public function reset()
82  {
83  self::resetStatic();
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 }
static getResponseFormat()
Checks the format of the response.
$style
Definition: example_012.php:70
$format
Definition: metadata.php:141
$context
Definition: webdav.php:25
static resetStatic()
Forget all logged records.
static writeOutput($str)
Wrapper for echo to allow overriding.
Base Handler class providing the Handler structure.
static send()
Convert records to javascript console commands and send it to the browser.
$records
Definition: simple_test.php:22
Handler sending logs to browser&#39;s javascript console with no browser extension required.
registerShutdownFunction()
Wrapper for register_shutdown_function to allow overriding.
Formats incoming records into a one-line string.
$key
Definition: croninfo.php:18