Namespaces

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

Classes

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

Interfaces

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