Packages

  • dibi
    • drivers
    • nette
    • reflection
  • None
  • PHP

Classes

  • DibiNetteExtension
  • DibiNettePanel
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the "dibi" - smart database abstraction layer.
  5:  *
  6:  * Copyright (c) 2005 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  */
 11: 
 12: 
 13: 
 14: if (interface_exists('Nette\Diagnostics\IBarPanel')) {
 15:     class_alias('Nette\Diagnostics\IBarPanel', 'IBarPanel');
 16: }
 17: 
 18: 
 19: 
 20: /**
 21:  * Dibi panel for Nette\Diagnostics.
 22:  *
 23:  * @author     David Grudl
 24:  * @package    dibi\nette
 25:  */
 26: class DibiNettePanel extends DibiObject implements IBarPanel
 27: {
 28:     /** @var int maximum SQL length */
 29:     static public $maxLength = 1000;
 30: 
 31:     /** @var bool  explain queries? */
 32:     public $explain;
 33: 
 34:     /** @var int */
 35:     public $filter;
 36: 
 37:     /** @var array */
 38:     private $events = array();
 39: 
 40: 
 41: 
 42:     public function __construct($explain = TRUE, $filter = NULL)
 43:     {
 44:         $this->filter = $filter ? (int) $filter : DibiEvent::QUERY;
 45:         $this->explain = (bool) $explain;
 46:     }
 47: 
 48: 
 49: 
 50:     public function register(DibiConnection $connection)
 51:     {
 52:         if (is_callable('Nette\Diagnostics\Debugger::enable')) {
 53:             class_alias('Nette\Diagnostics\Debugger', 'NDebugger'); // PHP 5.2 code compatibility
 54:         }
 55:         if (is_callable('NDebugger::enable')) {
 56:             NDebugger::$bar && NDebugger::$bar->addPanel($this);
 57:             NDebugger::$blueScreen && NDebugger::$blueScreen->addPanel(array($this, 'renderException'), __CLASS__);
 58:             $connection->onEvent[] = array($this, 'logEvent');
 59:         } elseif (is_callable('Debugger::enable')) {
 60:             Debugger::$bar && Debugger::$bar->addPanel($this);
 61:             Debugger::$blueScreen && Debugger::$blueScreen->addPanel(array($this, 'renderException'), __CLASS__);
 62:             $connection->onEvent[] = array($this, 'logEvent');
 63:         }
 64:     }
 65: 
 66: 
 67: 
 68:     /**
 69:      * After event notification.
 70:      * @return void
 71:      */
 72:     public function logEvent(DibiEvent $event)
 73:     {
 74:         if (($event->type & $this->filter) === 0) {
 75:             return;
 76:         }
 77:         $this->events[] = $event;
 78:     }
 79: 
 80: 
 81: 
 82:     /**
 83:      * Returns blue-screen custom tab.
 84:      * @return mixed
 85:      */
 86:     public function renderException($e)
 87:     {
 88:         if ($e instanceof DibiException && $e->getSql()) {
 89:             return array(
 90:                 'tab' => 'SQL',
 91:                 'panel' => dibi::dump($e->getSql(), TRUE),
 92:             );
 93:         }
 94:     }
 95: 
 96: 
 97: 
 98:     /**
 99:      * Returns HTML code for custom tab. (Nette\Diagnostics\IBarPanel)
100:      * @return mixed
101:      */
102:     public function getTab()
103:     {
104:         return '<span title="dibi"><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" />'
105:             . dibi::$numOfQueries . ' queries'
106:             . (dibi::$totalTime ? ' / ' . sprintf('%0.1f', dibi::$totalTime * 1000) . 'ms' : '')
107:             . '</span>';
108:     }
109: 
110: 
111: 
112:     /**
113:      * Returns HTML code for custom panel. (Nette\Diagnostics\IBarPanel)
114:      * @return mixed
115:      */
116:     public function getPanel()
117:     {
118:         $s = NULL;
119:         $h = 'htmlSpecialChars';
120:         foreach ($this->events as $event) {
121:             $explain = NULL; // EXPLAIN is called here to work SELECT FOUND_ROWS()
122:             if ($this->explain && $event->type === DibiEvent::SELECT) {
123:                 try {
124:                     $backup = array($event->connection->onEvent, dibi::$numOfQueries, dibi::$totalTime);
125:                     $event->connection->onEvent = NULL;
126:                     $explain = dibi::dump($event->connection->nativeQuery('EXPLAIN ' . $event->sql), TRUE);
127:                 } catch (DibiException $e) {}
128:                 list($event->connection->onEvent, dibi::$numOfQueries, dibi::$totalTime) = $backup;
129:             }
130: 
131:             $s .= '<tr><td>' . sprintf('%0.3f', $event->time * 1000);
132:             if ($explain) {
133:                 static $counter;
134:                 $counter++;
135:                 $s .= "<br /><a href='#' class='nette-toggler' rel='#nette-debug-DibiProfiler-row-$counter'>explain&nbsp;&#x25ba;</a>";
136:             }
137: 
138:             $s .= '</td><td class="nette-DibiProfiler-sql">' . dibi::dump(strlen($event->sql) > self::$maxLength ? substr($event->sql, 0, self::$maxLength) . '...' : $event->sql, TRUE);
139:             if ($explain) {
140:                 $s .= "<div id='nette-debug-DibiProfiler-row-$counter' class='nette-collapsed'>{$explain}</div>";
141:             }
142:             if ($event->source) {
143:                 $helpers = 'Nette\Diagnostics\Helpers';
144:                 if (!class_exists($helpers)) {
145:                     $helpers = class_exists('NDebugHelpers') ? 'NDebugHelpers' : 'DebugHelpers';
146:                 }
147:                 $s .= call_user_func(array($helpers, 'editorLink'), $event->source[0], $event->source[1])->class('nette-DibiProfiler-source');
148:             }
149: 
150:             $s .= "</td><td>{$event->count}</td><td>{$h($event->connection->getConfig('driver') . '/' . $event->connection->getConfig('name'))}</td></tr>";
151:         }
152: 
153:         return empty($this->events) ? '' :
154:             '<style> #nette-debug td.nette-DibiProfiler-sql { background: white !important }
155:             #nette-debug .nette-DibiProfiler-source { color: #999 !important }
156:             #nette-debug nette-DibiProfiler tr table { margin: 8px 0; max-height: 150px; overflow:auto } </style>
157:             <h1>Queries: ' . dibi::$numOfQueries . (dibi::$totalTime === NULL ? '' : ', time: ' . sprintf('%0.3f', dibi::$totalTime * 1000) . ' ms') . '</h1>
158:             <div class="nette-inner nette-DibiProfiler">
159:             <table>
160:                 <tr><th>Time&nbsp;ms</th><th>SQL Statement</th><th>Rows</th><th>Connection</th></tr>' . $s . '
161:             </table>
162:             </div>';
163:     }
164: 
165: }
166: 
dibi API documentation API documentation generated by ApiGen 2.3.0