1 <?php
2 3 4 5 6 7 8 9 10
11
12 namespace Neevo\Nette;
13
14 use Exception;
15 use Neevo\Manager;
16 use Neevo\NeevoException;
17 use Neevo\ObservableInterface;
18 use Neevo\ObserverInterface;
19 use Neevo\Result;
20 use Nette\Diagnostics\BlueScreen;
21 use Nette\Diagnostics\Helpers;
22 use Nette\Diagnostics\IBarPanel;
23 use Nette\Reflection\ClassType;
24
25
26 27 28
29 class DebugPanel implements ObserverInterface, IBarPanel {
30
31
32 private $name;
33
34
35 private $tickets = array();
36
37
38 private $numQueries = 0;
39
40
41 private $totalTime = 0;
42
43
44 private $failedQuerySource;
45
46
47 private $explain = true;
48
49
50 51 52
53 public function __construct($name = 'Default'){
54 $this->name = $name;
55 }
56
57
58 59 60
61 public function getExplain(){
62 return $this->explain;
63 }
64
65
66 67 68
69 public function setExplain($explain){
70 $this->explain = (bool) $explain;
71 }
72
73
74 75 76
77 public function getTickets(){
78 return $this->tickets;
79 }
80
81
82 83 84
85 public function getNumQueries(){
86 return $this->numQueries;
87 }
88
89
90 91 92
93 public function getTotalTime(){
94 return $this->totalTime;
95 }
96
97
98 99 100 101 102
103 public function updateStatus(ObservableInterface $subject, $event){
104 $source = null;
105 if(class_exists('Neevo\Manager')){
106 $path = dirname(ClassType::from('Neevo\Manager')->getFileName());
107 foreach(debug_backtrace(false) as $t){
108 if(isset($t['file']) && strpos($t['file'], $path) !== 0){
109 $source = array($t['file'], (int) $t['line']);
110 break;
111 }
112 }
113 }
114
115 if($event & self::QUERY){
116 $this->numQueries++;
117 $this->totalTime += $subject->getTime();
118
119 if($subject instanceof Result){
120 try{
121 $rows = count($subject);
122 } catch(Exception $e){
123 $rows = '?';
124 }
125 $explain = $this->explain ? $subject->explain() : null;
126 } else
127 $rows = '-';
128
129 $this->tickets[] = array(
130 'sql' => (string) $subject,
131 'time' => $subject->getTime(),
132 'rows' => $rows,
133 'source' => $source,
134 'connection' => $subject->getConnection(),
135 'explain' => isset($explain) ? $explain : null
136 );
137 } elseif($event === self::EXCEPTION)
138 $this->failedQuerySource = $source;
139 }
140
141
142 143 144 145 146
147 public function renderException($e){
148 if(!($e instanceof NeevoException && $e->getSql()))
149 return;
150 list($file, $line) = $this->failedQuerySource;
151 return array(
152 'tab' => 'SQL',
153 'panel' => Manager::highlightSql($e->getSql())
154 . '<p><b>File:</b> ' . Helpers::editorLink($file, $line) . '</p>'
155 . ($line ? BlueScreen::highlightFile($file, $line) : '')
156 . 'Neevo v' . Manager::VERSION
157 );
158 }
159
160
161 162 163 164
165 public function getTab(){
166 $name = $this->name;
167 $queries = $this->numQueries;
168 $time = $this->totalTime;
169 ob_start();
170 include __DIR__ . '/templates/DebugPanel.tab.phtml';
171 return ob_get_clean();
172 }
173
174
175 176 177 178
179 public function getPanel(){
180 if(!$this->numQueries)
181 return '';
182
183 $name = $this->name;
184 $tickets = $this->tickets;
185 $totalTime = $this->totalTime;
186 $numQueries = $this->numQueries;
187
188 ob_start();
189 include __DIR__ . '/templates/DebugPanel.panel.phtml';
190 return ob_get_clean();
191 }
192
193
194 }