/** * Function prints from where were method/function called * @author Filip Procházka <*****@*****.**> * * @param int $level * @param bool $return * @param bool $fullTrace */ function wc($level = 1, $return = FALSE, $fullTrace = FALSE) { if (Debugger::$productionMode) { return; } $o = function ($t) { return (isset($t->class) ? htmlspecialchars($t->class) . "->" : NULL) . htmlspecialchars($t->function) . '()'; }; $f = function ($t) { return isset($t->file) ? '(' . Helpers::editorLink($t->file, $t->line) . ')' : NULL; }; $trace = debug_backtrace(); $target = (object) $trace[$level]; $caller = (object) $trace[$level + 1]; $message = NULL; if ($fullTrace) { array_shift($trace); foreach ($trace as $call) { $message .= $o((object) $call) . " \n"; } } else { $message = $o($target) . " called from " . $o($caller) . $f($caller); } if ($return) { return strip_tags($message); } echo "<pre class='nette-dump'>" . nl2br($message) . "</pre>"; }
private function renderHtml() { $res = '<style>code, pre {white-space:nowrap} a {text-decoration:none} pre {color:gray;display:inline} big {color:red}</style><code>'; foreach ($this->list as $item) { $res .= Helpers::editorLink($item[0], $item[1]) . ' ' . str_replace(self::BOM, '<big>BOM</big>', Dumper::toHtml($item[2])) . "<br>\n"; } return $res . '</code>'; }
/** * @param array * @return string */ protected function processQuery(array $query) { $s = ''; $h = 'htmlSpecialChars'; list($sql, $params, $time, $rows, $connection, $source) = $query; $s .= '<tr><td>' . sprintf('%0.3f', $time * 1000); $s .= '</td><td class="nette-Doctrine2Panel-sql">' . Connection::highlightSql($sql); if ($source) { list($file, $line) = $source; if (Debugger::$editor) { $s .= \Nette\Diagnostics\Helpers::editorLink($file, $line); } else { $s .= "<span class='nette-Doctrine2Panel-source' title='{$h($file)}:$line'>" . $h(basename(dirname($file)) . '/' . basename($file)) . ":" . $line . "</span>"; } } $s .= '</td><td>'; $s .= \Nette\Diagnostics\Helpers::clickableDump($params, TRUE); $s .= '</td><td>' . $rows . '</td></tr>'; return $s; }
/** * Dumps information about a variable in readable format. * @param mixed variable to dump * @param bool return output instead of printing it? (bypasses $productionMode) * @return mixed variable itself or dump */ public static function dump($var, $return = FALSE) { if (!$return && self::$productionMode) { return $var; } $output = "<pre class=\"nette-dump\">" . Helpers::htmlDump($var) . "</pre>\n"; if (!$return) { $trace = debug_backtrace(FALSE); $i = Helpers::findTrace($trace, 'dump') ? 1 : 0; if (isset($trace[$i]['file'], $trace[$i]['line']) && is_file($trace[$i]['file'])) { $lines = file($trace[$i]['file']); preg_match('#dump\\((.*)\\)#', $lines[$trace[$i]['line'] - 1], $m); $output = substr_replace($output, ' title="' . htmlspecialchars((isset($m[0]) ? "{$m['0']} \n" : '') . "in file {$trace[$i]['file']} on line {$trace[$i]['line']}") . '"', 4, 0); if (self::$showLocation) { $output = substr_replace($output, ' <small>in ' . Helpers::editorLink($trace[$i]['file'], $trace[$i]['line']) . ":{$trace[$i]['line']}</small>", -8, 0); } } } if (self::$consoleMode) { if (self::$consoleColors && substr(getenv('TERM'), 0, 5) === 'xterm') { $output = preg_replace_callback('#<span class="php-(\\w+)">|</span>#', function ($m) { return "[" . (isset($m[1], Debugger::$consoleColors[$m[1]]) ? Debugger::$consoleColors[$m[1]] : '0') . "m"; }, $output); } $output = htmlspecialchars_decode(strip_tags($output), ENT_QUOTES); } if ($return) { return $output; } else { echo $output; return $var; } }
public function getPanel() { $this->disabled = TRUE; $s = ''; foreach ($this->queries as $query) { list($connection, $sql, $params, $source, $time, $rows, $error) = $query; $explain = NULL; // EXPLAIN is called here to work SELECT FOUND_ROWS() if (!$error && $this->explain && preg_match('#\\s*\\(?\\s*SELECT\\s#iA', $sql)) { try { $cmd = is_string($this->explain) ? $this->explain : 'EXPLAIN'; $explain = $connection->queryArgs("{$cmd} {$sql}", $params)->fetchAll(); } catch (\PDOException $e) { } } $s .= '<tr><td>'; if ($error) { $s .= '<span title="' . htmlSpecialChars($error, ENT_IGNORE | ENT_QUOTES) . '">ERROR</span>'; } elseif ($time !== NULL) { $s .= sprintf('%0.3f', $time * 1000); } if ($explain) { static $counter; $counter++; $s .= "<br /><a class='nette-toggle-collapsed' href='#nette-DbConnectionPanel-row-{$counter}'>explain</a>"; } $s .= '</td><td class="nette-DbConnectionPanel-sql">' . Helpers::dumpSql($sql, $params); if ($explain) { $s .= "<table id='nette-DbConnectionPanel-row-{$counter}' class='nette-collapsed'><tr>"; foreach ($explain[0] as $col => $foo) { $s .= '<th>' . htmlSpecialChars($col) . '</th>'; } $s .= "</tr>"; foreach ($explain as $row) { $s .= "<tr>"; foreach ($row as $col) { $s .= '<td>' . htmlSpecialChars($col) . '</td>'; } $s .= "</tr>"; } $s .= "</table>"; } if ($source) { $s .= Nette\Diagnostics\Helpers::editorLink($source[0], $source[1])->class('nette-DbConnectionPanel-source'); } $s .= '</td><td>' . $rows . '</td></tr>'; } return $this->count ? '<style class="nette-debug"> #nette-debug td.nette-DbConnectionPanel-sql { background: white !important } #nette-debug .nette-DbConnectionPanel-source { color: #BBB !important } </style> <h1 title="' . htmlSpecialChars($connection->getDsn()) . '">Queries: ' . $this->count . ($this->totalTime ? ', time: ' . sprintf('%0.3f', $this->totalTime * 1000) . ' ms' : '') . ', ' . htmlSpecialChars($this->name) . '</h1> <div class="nette-inner nette-DbConnectionPanel"> <table> <tr><th>Time ms</th><th>SQL Query</th><th>Rows</th></tr>' . $s . ' </table>' . (count($this->queries) < $this->count ? '<p>...and more</p>' : '') . '</div>' : ''; }
public function getPanel() { $this->disabled = TRUE; $s = ''; $h = 'htmlSpecialChars'; foreach ($this->queries as $i => $query) { list($sql, $params, $time, $rows, $connection, $source) = $query; $explain = NULL; // EXPLAIN is called here to work SELECT FOUND_ROWS() if ($this->explain && preg_match('#\\s*SELECT\\s#iA', $sql)) { try { $explain = $connection->queryArgs('EXPLAIN ' . $sql, $params)->fetchAll(); } catch (\PDOException $e) { } } $s .= '<tr><td>' . sprintf('%0.3f', $time * 1000); if ($explain) { static $counter; $counter++; $s .= "<br /><a href='#' class='nette-toggler' rel='#nette-DbConnectionPanel-row-{$counter}'>explain ►</a>"; } $s .= '</td><td class="nette-DbConnectionPanel-sql">' . Connection::highlightSql(Nette\Utils\Strings::truncate($sql, self::$maxLength)); if ($explain) { $s .= "<table id='nette-DbConnectionPanel-row-{$counter}' class='nette-collapsed'><tr>"; foreach ($explain[0] as $col => $foo) { $s .= "<th>{$h($col)}</th>"; } $s .= "</tr>"; foreach ($explain as $row) { $s .= "<tr>"; foreach ($row as $col) { $s .= "<td>{$h($col)}</td>"; } $s .= "</tr>"; } $s .= "</table>"; } if ($source) { $s .= Nette\Diagnostics\Helpers::editorLink($source[0], $source[1])->class('nette-DbConnectionPanel-source'); } $s .= '</td><td>'; foreach ($params as $param) { $s .= Debugger::dump($param, TRUE); } $s .= '</td><td>' . $rows . '</td></tr>'; } return empty($this->queries) ? '' : '<style> #nette-debug td.nette-DbConnectionPanel-sql { background: white !important } #nette-debug .nette-DbConnectionPanel-source { color: #BBB !important } #nette-debug nette-DbConnectionPanel tr table { margin: 8px 0; max-height: 150px; overflow:auto } </style> <h1>Queries: ' . count($this->queries) . ($this->totalTime ? ', time: ' . sprintf('%0.3f', $this->totalTime * 1000) . ' ms' : '') . '</h1> <div class="nette-inner nette-DbConnectionPanel"> <table> <tr><th>Time ms</th><th>SQL Statement</th><th>Params</th><th>Rows</th></tr>' . $s . ' </table> </div>'; }
/** * @return BlueScreen */ public static function getBlueScreen() { if (!self::$blueScreen) { self::$blueScreen = new BlueScreen(); self::$blueScreen->collapsePaths[] = dirname(__DIR__); self::$blueScreen->addPanel(function ($e) { if ($e instanceof Nette\Templating\FilterException) { return array('tab' => 'Template', 'panel' => '<p><b>File:</b> ' . Helpers::editorLink($e->sourceFile, $e->sourceLine) . '</p>' . ($e->sourceLine ? BlueScreen::highlightFile($e->sourceFile, $e->sourceLine) : '')); } elseif ($e instanceof Nette\Utils\NeonException && preg_match('#line (\\d+)#', $e->getMessage(), $m)) { if ($item = Helpers::findTrace($e->getTrace(), 'Nette\\DI\\Config\\Adapters\\NeonAdapter::load')) { return array('tab' => 'NEON', 'panel' => '<p><b>File:</b> ' . Helpers::editorLink($item['args'][0], $m[1]) . '</p>' . BlueScreen::highlightFile($item['args'][0], $m[1])); } elseif ($item = Helpers::findTrace($e->getTrace(), 'Nette\\Utils\\Neon::decode')) { return array('tab' => 'NEON', 'panel' => BlueScreen::highlightPhp($item['args'][0], $m[1])); } } }); } return self::$blueScreen; }
function getPanel() { $this->disabled = TRUE; $s = ''; foreach ($this->queries as $i => $query) { list($sql, $params, $time, $rows, $connection, $source) = $query; $explain = NULL; if ($this->explain && preg_match('#\\s*\\(?\\s*SELECT\\s#iA', $sql)) { try { $cmd = is_string($this->explain) ? $this->explain : 'EXPLAIN'; $explain = $connection->queryArgs("{$cmd} {$sql}", $params)->fetchAll(); } catch (\PDOException $e) { } } $s .= '<tr><td>' . sprintf('%0.3f', $time * 1000); if ($explain) { static $counter; $counter++; $s .= "<br /><a href='#' class='nette-toggler' rel='#nette-DbConnectionPanel-row-{$counter}'>explain ►</a>"; } $s .= '</td><td class="nette-DbConnectionPanel-sql">' . Helpers::dumpSql(self::$maxLength ? Nette\Utils\Strings::truncate($sql, self::$maxLength) : $sql); if ($explain) { $s .= "<table id='nette-DbConnectionPanel-row-{$counter}' class='nette-collapsed'><tr>"; foreach ($explain[0] as $col => $foo) { $s .= '<th>' . htmlSpecialChars($col) . '</th>'; } $s .= "</tr>"; foreach ($explain as $row) { $s .= "<tr>"; foreach ($row as $col) { $s .= '<td>' . htmlSpecialChars($col) . '</td>'; } $s .= "</tr>"; } $s .= "</table>"; } if ($source) { $s .= Nette\Diagnostics\Helpers::editorLink($source[0], $source[1])->class('nette-DbConnectionPanel-source'); } $s .= '</td><td>'; foreach ($params as $param) { $s .= Debugger::dump($param, TRUE); } $s .= '</td><td>' . $rows . '</td></tr>'; } return empty($this->queries) ? '' : '<style class="nette-debug"> #nette-debug td.nette-DbConnectionPanel-sql { background: white !important } #nette-debug .nette-DbConnectionPanel-source { color: #BBB !important } </style> <h1 title="' . htmlSpecialChars($connection->getDsn()) . '">Queries: ' . count($this->queries) . ($this->totalTime ? ', time: ' . sprintf('%0.3f', $this->totalTime * 1000) . ' ms' : '') . ', ' . htmlSpecialChars($this->name) . '</h1> <div class="nette-inner nette-DbConnectionPanel"> <table> <tr><th>Time ms</th><th>SQL Statement</th><th>Params</th><th>Rows</th></tr>' . $s . ' </table> </div>'; }
function getPanel() { ob_start(); $data = $this->data; if ($this->id === 'dumps') { ?> <style class="nette-debug">#nette-debug .nette-DumpPanel h2{font:11pt/1.5 sans-serif;margin:0;padding:2px 8px;background:#3484d2;color:white}#nette-debug .nette-DumpPanel table{width:100%}#nette-debug .nette-DumpPanel a{color:#333;background:transparent}#nette-debug .nette-DumpPanel a abbr{font-family:sans-serif;color:#999}#nette-debug .nette-DumpPanel pre .php-array,#nette-debug .nette-DumpPanel pre .php-object{color:#c16549}</style> <h1>Dumped variables</h1> <div class="nette-inner nette-DumpPanel"> <?php foreach ($data as $item) { ?> <?php if ($item['title']) { ?> <h2><?php echo htmlspecialchars($item['title']); ?> </h2> <?php } ?> <table> <?php $i = 0; ?> <?php foreach ($item['dump'] as $key => $dump) { ?> <tr class="<?php echo $i++ % 2 ? 'nette-alt' : ''; ?> "> <th><?php echo htmlspecialchars($key); ?> </th> <td><?php echo $dump; ?> </td> </tr> <?php } ?> </table> <?php } ?> </div> <?php } elseif ($this->id === 'errors') { ?> <h1>Errors</h1> <div class="nette-inner"> <table> <?php $i = 0; foreach ($data as $item => $count) { list($file, $line, $message) = explode('|', $item, 3); ?> <tr class="<?php echo $i++ % 2 ? 'nette-alt' : ''; ?> "> <td class="nette-right"><?php echo $count ? "{$count}×" : ''; ?> </td> <td><pre><?php echo htmlspecialchars(Nette\Utils\Strings::fixEncoding($message)), ' in ', Helpers::editorLink($file, $line), ':', $line; ?> </pre></td> </tr> <?php } ?> </table> </div> <?php } return ob_get_clean(); }
/** * Dumps information about a variable in readable format. * @param mixed variable to dump * @param bool return output instead of printing it? (bypasses $productionMode) * @return mixed variable itself or dump */ public static function dump($var, $return = FALSE) { if (!$return && self::$productionMode) { return $var; } $output = "<pre class=\"nette-dump\">" . Helpers::htmlDump($var) . "</pre>\n"; if (!$return) { $trace = debug_backtrace(); $i = !isset($trace[1]['class']) && isset($trace[1]['function']) && $trace[1]['function'] === 'dump' ? 1 : 0; if (isset($trace[$i]['file'], $trace[$i]['line']) && is_file($trace[$i]['file'])) { $lines = file($trace[$i]['file']); preg_match('#dump\\((.*)\\)#', $lines[$trace[$i]['line'] - 1], $m); $output = substr_replace($output, ' title="' . htmlspecialchars((isset($m[0]) ? "{$m['0']} \n" : '') . "in file {$trace[$i]['file']} on line {$trace[$i]['line']}") . '"', 4, 0); if (self::$showLocation) { $output = substr_replace($output, ' <small>in ' . Helpers::editorLink($trace[$i]['file'], $trace[$i]['line']) . ":{$trace[$i]['line']}</small>", -8, 0); } } } if (self::$consoleMode) { $output = htmlspecialchars_decode(strip_tags($output), ENT_NOQUOTES); } if ($return) { return $output; } else { echo $output; return $var; } }
getTab(){return'<span title="Nette\\Database '.htmlSpecialChars($this->name).'">'.'<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEYSURBVBgZBcHPio5hGAfg6/2+R980k6wmJgsJ5U/ZOAqbSc2GnXOwUg7BESgLUeIQ1GSjLFnMwsKGGg1qxJRmPM97/1zXFAAAAEADdlfZzr26miup2svnelq7d2aYgt3rebl585wN6+K3I1/9fJe7O/uIePP2SypJkiRJ0vMhr55FLCA3zgIAOK9uQ4MS361ZOSX+OrTvkgINSjS/HIvhjxNNFGgQsbSmabohKDNoUGLohsls6BaiQIMSs2FYmnXdUsygQYmumy3Nhi6igwalDEOJEjPKP7CA2aFNK8Bkyy3fdNCg7r9/fW3jgpVJbDmy5+PB2IYp4MXFelQ7izPrhkPHB+P5/PjhD5gCgCenx+VR/dODEwD+A3T7nqbxwf1HAAAAAElFTkSuQmCC" />'.count($this->queries).' queries'.($this->totalTime?' / '.sprintf('%0.1f',$this->totalTime*1000).'ms':'').'</span>';}function getPanel(){$this->disabled=TRUE;$s='';$h='htmlSpecialChars';foreach($this->queries as$i=>$query){list($sql,$params,$time,$rows,$connection,$source)=$query;$explain=NULL;if($this->explain&&preg_match('#\s*\(?\s*SELECT\s#iA',$sql)){try{$cmd=is_string($this->explain)?$this->explain:'EXPLAIN';$explain=$connection->queryArgs("$cmd $sql",$params)->fetchAll();}catch(\PDOException$e){}}$s.='<tr><td>'.sprintf('%0.3f',$time*1000);if($explain){static$counter;$counter++;$s.="<br /><a href='#' class='nette-toggler' rel='#nette-DbConnectionPanel-row-$counter'>explain ►</a>";}$s.='</td><td class="nette-DbConnectionPanel-sql">'.Helpers::dumpSql(self::$maxLength?Nette\Utils\Strings::truncate($sql,self::$maxLength):$sql);if($explain){$s.="<table id='nette-DbConnectionPanel-row-$counter' class='nette-collapsed'><tr>";foreach($explain[0]as$col=>$foo){$s.="<th>{$h($col)}</th>";}$s.="</tr>";foreach($explain as$row){$s.="<tr>";foreach($row as$col){$s.="<td>{$h($col)}</td>";}$s.="</tr>";}$s.="</table>";}if($source){$s.=Nette\Diagnostics\Helpers::editorLink($source[0],$source[1])->class('nette-DbConnectionPanel-source');}$s.='</td><td>';foreach($params as$param){$s.=Debugger::dump($param,TRUE);}$s.='</td><td>'.$rows.'</td></tr>';}return empty($this->queries)?'':'<style> #nette-debug td.nette-DbConnectionPanel-sql { background: white !important } #nette-debug .nette-DbConnectionPanel-source { color: #BBB !important } </style> <h1>Queries: '.count($this->queries).($this->totalTime?', time: '.sprintf('%0.3f',$this->totalTime*1000).' ms':'').'</h1> <div class="nette-inner nette-DbConnectionPanel"> <table> <tr><th>Time ms</th><th>SQL Statement</th><th>Params</th><th>Rows</th></tr>'.$s.' </table> </div>';}}}namespace Nette\Database\Drivers{use
/** * Extend debugger bluescreen * * @param mixed $exception Exception * * @return array */ public static function renderException($exception) { if ($exception instanceof \UniMapper\Exception\EntityException && $exception->getEntityPath() !== false) { $link = Helpers::editorLink($exception->getEntityPath(), $exception->getEntityLine()); $code = BlueScreen::highlightFile($exception->getEntityPath(), $exception->getEntityLine()); return ["tab" => "Entity", "panel" => $link . "\n" . $code]; } elseif ($exception instanceof \UniMapper\Exception\InvalidArgumentException && $exception->getValue() !== null) { return ["tab" => "Value given", "panel" => self::dump($exception->getValue())]; } elseif ($exception instanceof \UniMapper\Exception\AdapterException && $exception->getQuery() !== null) { return ["tab" => "Query", "panel" => self::dump($exception->getQuery())]; } }
public function getPanel() { $this->disabled = TRUE; $s = ''; $h = 'htmlSpecialChars'; $counts = array(); $transactionTime = null; foreach ($this->queries as $i => $query) { list($sql, $params, $time, $rows, $connection, $source) = $query; $command = ''; if (preg_match('#^\\s*(\\w+)#', $sql, $m)) { $command = strtoupper($m[1]); @$counts[$command]++; } if ($sql == 'TRANSACTION BEGIN') { $transactionTime = 0; } elseif (preg_match('#TRANSACTION (COMMIT|ROLLBACK)#', $sql)) { $time = $transactionTime; $transactionTime = null; } elseif ($transactionTime !== null) { $transactionTime += $time; } foreach ((array) $params as $param) { if (!is_numeric($param)) { $param = str_replace("'", "\\'", $param); } $sql = preg_replace('#\\?#', "'{$param}'", $sql, 1); } $explain = NULL; // EXPLAIN is called here to work SELECT FOUND_ROWS() if ($this->explain && preg_match('#\\s*\\(?\\s*SELECT\\s#iA', $sql)) { try { $cmd = is_string($this->explain) ? $this->explain : 'EXPLAIN'; $explain = $connection->queryArgs("{$cmd} {$sql}", $params)->fetchAll(); } catch (PDOException $e) { } } $s .= "<tr class='nette-DbConnectionPanel-type-{$command}'><td>" . sprintf('%0.3f', $time * 1000); if ($explain) { static $counter; $counter++; $s .= "<br /><a href='#' class='nette-toggle-collapsed' data-ref='#nette-DbConnectionPanel-row-{$counter}'>explain </a>"; } $s .= '</td><td class="nette-DbConnectionPanel-sql">' . Helpers::dumpSql(self::$maxLength ? Nette\Utils\Strings::truncate($sql, self::$maxLength) : $sql); if ($explain) { $s .= "<table id='nette-DbConnectionPanel-row-{$counter}' class='nette-collapsed'><tr>"; foreach ($explain[0] as $col => $foo) { $s .= "<th>{$h($col)}</th>"; } $s .= "</tr>"; foreach ($explain as $row) { $s .= "<tr>"; foreach ($row as $col) { $s .= "<td>{$h($col)}</td>"; } $s .= "</tr>"; } $s .= "</table>"; } if ($source) { $s .= Nette\Diagnostics\Helpers::editorLink($source[0], $source[1])->class('nette-DbConnectionPanel-source'); } $s .= '</td>'; $s .= '<td>' . $rows . '</td></tr>'; } $c = ''; foreach ($counts as $command => $count) { $c .= "<tr><th>{$command}</th><td>{$count}</td><td><input type='checkbox' class='nette-DbConnectionPanel-type-switcher' name='{$command}' id='nette-DbConnectionPanel-type-{$command}' checked='checked' /></td></tr>"; } return empty($this->queries) ? '' : '<style> #nette-debug td.nette-DbConnectionPanel-sql { background: white !important } #nette-debug .nette-DbConnectionPanel-source { color: #BBB !important } </style> <script type="text/javascript"> (function() { var FW = typeof Tracy !== "undefined" ? Tracy : Nette; var $ = typeof FW.Q !== "undefined" ? FW.Q.factory : FW.Query.factory; $(".nette-DbConnectionPanel-type-switcher").bind("click", function(e) { var name = this.name; if (this.checked) { $(".nette-DbConnectionPanel-type-" + name).show(); } else { $(".nette-DbConnectionPanel-type-" + name).hide(); } }); })(); </script> <h1>Queries: ' . count($this->queries) . ($this->totalTime ? ', time: ' . sprintf('%0.3f', $this->totalTime * 1000) . ' ms' : '') . '</h1> <div class="nette-inner nette-DbConnectionPanel"> <table> <tr><th>Type</th><th>Count</th><th>Filter</th></tr>' . $c . ' </table> <br /> <table> <tr><th>Time ms</th><th>SQL Statement</th><th>Rows</th></tr>' . $s . ' </table> </div>'; }