Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationLatte
      • ApplicationTracy
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsLatte
      • Framework
      • HttpTracy
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy

Classes

  • Bar
  • BlueScreen
  • Debugger
  • Dumper
  • FireLogger
  • Helpers
  • Logger
  • OutputDebugger

Interfaces

  • IBarPanel
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Tracy (https://tracy.nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Tracy;
  9: 
 10: use Tracy;
 11: 
 12: 
 13: /**
 14:  * Red BlueScreen.
 15:  *
 16:  * @author     David Grudl
 17:  */
 18: class BlueScreen
 19: {
 20:     /** @var string[] */
 21:     public $info = array();
 22: 
 23:     /** @var callable[] */
 24:     private $panels = array();
 25: 
 26:     /** @var string[] paths to be collapsed in stack trace (e.g. core libraries) */
 27:     public $collapsePaths = array();
 28: 
 29: 
 30:     public function __construct()
 31:     {
 32:         $this->collapsePaths[] = preg_match('#(.+/vendor)/tracy/tracy/src/Tracy$#', strtr(__DIR__, '\\', '/'), $m)
 33:             ? $m[1]
 34:             : __DIR__;
 35:     }
 36: 
 37: 
 38:     /**
 39:      * Add custom panel.
 40:      * @param  callable
 41:      * @return self
 42:      */
 43:     public function addPanel($panel)
 44:     {
 45:         if (!in_array($panel, $this->panels, TRUE)) {
 46:             $this->panels[] = $panel;
 47:         }
 48:         return $this;
 49:     }
 50: 
 51: 
 52:     /**
 53:      * Renders blue screen.
 54:      * @param  \Exception|\Throwable
 55:      * @return void
 56:      */
 57:     public function render($exception)
 58:     {
 59:         $panels = $this->panels;
 60:         $info = array_filter($this->info);
 61:         require __DIR__ . '/templates/bluescreen.phtml';
 62:     }
 63: 
 64: 
 65:     /**
 66:      * Returns syntax highlighted source code.
 67:      * @param  string
 68:      * @param  int
 69:      * @param  int
 70:      * @return string
 71:      */
 72:     public static function highlightFile($file, $line, $lines = 15, array $vars = NULL)
 73:     {
 74:         $source = @file_get_contents($file); // intentionally @
 75:         if ($source) {
 76:             $source = static::highlightPhp($source, $line, $lines, $vars);
 77:             if ($editor = Helpers::editorUri($file, $line)) {
 78:                 $source = substr_replace($source, ' data-tracy-href="' . htmlspecialchars($editor, ENT_QUOTES, 'UTF-8') . '"', 4, 0);
 79:             }
 80:             return $source;
 81:         }
 82:     }
 83: 
 84: 
 85:     /**
 86:      * Returns syntax highlighted source code.
 87:      * @param  string
 88:      * @param  int
 89:      * @param  int
 90:      * @return string
 91:      */
 92:     public static function highlightPhp($source, $line, $lines = 15, array $vars = NULL)
 93:     {
 94:         if (function_exists('ini_set')) {
 95:             ini_set('highlight.comment', '#998; font-style: italic');
 96:             ini_set('highlight.default', '#000');
 97:             ini_set('highlight.html', '#06B');
 98:             ini_set('highlight.keyword', '#D24; font-weight: bold');
 99:             ini_set('highlight.string', '#080');
100:         }
101: 
102:         $source = str_replace(array("\r\n", "\r"), "\n", $source);
103:         $source = explode("\n", highlight_string($source, TRUE));
104:         $out = $source[0]; // <code><span color=highlight.html>
105:         $source = str_replace('<br />', "\n", $source[1]);
106:         $out .= static::highlightLine($source, $line, $lines);
107: 
108:         if ($vars) {
109:             $out = preg_replace_callback('#">\$(\w+)(&nbsp;)?</span>#', function ($m) use ($vars) {
110:                 return array_key_exists($m[1], $vars)
111:                     ? '" title="'
112:                         . str_replace('"', '&quot;', trim(strip_tags(Dumper::toHtml($vars[$m[1]], array(Dumper::DEPTH => 1)))))
113:                         . $m[0]
114:                     : $m[0];
115:             }, $out);
116:         }
117: 
118:         $out = str_replace('&nbsp;', ' ', $out);
119:         return "<pre class='php'><div>$out</div></pre>";
120:     }
121: 
122: 
123: 
124:     /**
125:      * Returns highlighted line in HTML code.
126:      * @return string
127:      */
128:     public static function highlightLine($html, $line, $lines = 15)
129:     {
130:         $source = explode("\n", "\n" . str_replace("\r\n", "\n", $html));
131:         $out = '';
132:         $spans = 1;
133:         $start = $i = max(1, $line - floor($lines * 2 / 3));
134:         while (--$i >= 1) { // find last highlighted block
135:             if (preg_match('#.*(</?span[^>]*>)#', $source[$i], $m)) {
136:                 if ($m[1] !== '</span>') {
137:                     $spans++;
138:                     $out .= $m[1];
139:                 }
140:                 break;
141:             }
142:         }
143: 
144:         $source = array_slice($source, $start, $lines, TRUE);
145:         end($source);
146:         $numWidth = strlen((string) key($source));
147: 
148:         foreach ($source as $n => $s) {
149:             $spans += substr_count($s, '<span') - substr_count($s, '</span');
150:             $s = str_replace(array("\r", "\n"), array('', ''), $s);
151:             preg_match_all('#<[^>]+>#', $s, $tags);
152:             if ($n == $line) {
153:                 $out .= sprintf(
154:                     "<span class='highlight'>%{$numWidth}s:    %s\n</span>%s",
155:                     $n,
156:                     strip_tags($s),
157:                     implode('', $tags[0])
158:                 );
159:             } else {
160:                 $out .= sprintf("<span class='line'>%{$numWidth}s:</span>    %s\n", $n, $s);
161:             }
162:         }
163:         $out .= str_repeat('</span>', $spans) . '</code>';
164:         return $out;
165:     }
166: 
167: 
168:     /**
169:      * Should a file be collapsed in stack trace?
170:      * @param  string
171:      * @return bool
172:      */
173:     public function isCollapsed($file)
174:     {
175:         foreach ($this->collapsePaths as $path) {
176:             if (strpos(strtr($file, '\\', '/'), strtr("$path/", '\\', '/')) === 0) {
177:                 return TRUE;
178:             }
179:         }
180:         return FALSE;
181:     }
182: 
183: }
184: 
Nette 2.2 API documentation generated by ApiGen 2.8.0