1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Diagnostics;
9:
10: use Nette;
11:
12:
13: 14: 15:
16: class OutputDebugger extends Nette\Object
17: {
18: const BOM = "\xEF\xBB\xBF";
19:
20:
21: private $list = array();
22:
23:
24: private $lastFile;
25:
26:
27: public static function enable()
28: {
29: $me = new static;
30: $me->start();
31: }
32:
33:
34: public function start()
35: {
36: foreach (get_included_files() as $file) {
37: if (fread(fopen($file, 'r'), 3) === self::BOM) {
38: $this->list[] = array($file, 1, self::BOM);
39: }
40: }
41: ob_start(array($this, 'handler'), PHP_VERSION_ID >= 50400 ? 1 : 2);
42: }
43:
44:
45: public function handler($s, $phase)
46: {
47: $trace = debug_backtrace(FALSE);
48: if (isset($trace[0]['file'], $trace[0]['line'])) {
49: if ($this->lastFile === $trace[0]['file']) {
50: $this->list[count($this->list) - 1][2] .= $s;
51: } else {
52: $this->list[] = array($this->lastFile = $trace[0]['file'], $trace[0]['line'], $s);
53: }
54: }
55: if ($phase === PHP_OUTPUT_HANDLER_FINAL) {
56: return $this->renderHtml();
57: }
58: }
59:
60:
61: private function renderHtml()
62: {
63: $res = '<style>code, pre {white-space:nowrap} a {text-decoration:none} pre {color:gray;display:inline} big {color:red}</style><code>';
64: foreach ($this->list as $item) {
65: $res .= Helpers::editorLink($item[0], $item[1]) . ' '
66: . str_replace(self::BOM, '<big>BOM</big>', Dumper::toHtml($item[2])) . "<br>\n";
67: }
68: return $res . '</code>';
69: }
70:
71: }
72: