Route and Results buttons updated.
[speedfreak] / Server / system / libraries / Profiler.php
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
2 /**
3  * Adds useful information to the bottom of the current page for debugging and optimization purposes.
4  *
5  * Benchmarks   - The times and memory usage of benchmarks run by the Benchmark library.
6  * Database     - The raw SQL and number of affected rows of Database queries.
7  * Session Data - Data stored in the current session if using the Session library.
8  * POST Data    - The name and values of any POST data submitted to the current page.
9  * Cookie Data  - All cookies sent for the current request.
10  *
11  * $Id: Profiler.php 4383 2009-06-03 00:17:24Z ixmatus $
12  *
13  * @package    Profiler
14  * @author     Kohana Team
15  * @copyright  (c) 2007-2008 Kohana Team
16  * @license    http://kohanaphp.com/license.html
17  */
18 class Profiler_Core {
19
20         protected $profiles = array();
21         protected $show;
22
23         public function __construct()
24         {
25                 // Add all built in profiles to event
26                 Event::add('profiler.run', array($this, 'benchmarks'));
27                 Event::add('profiler.run', array($this, 'database'));
28                 Event::add('profiler.run', array($this, 'session'));
29                 Event::add('profiler.run', array($this, 'post'));
30                 Event::add('profiler.run', array($this, 'cookies'));
31
32                 // Add profiler to page output automatically
33                 Event::add('system.display', array($this, 'render'));
34
35                 Kohana::log('debug', 'Profiler Library initialized');
36         }
37
38         /**
39          * Magic __call method. Creates a new profiler section object.
40          *
41          * @param   string   input type
42          * @param   string   input name
43          * @return  object
44          */
45         public function __call($method, $args)
46         {
47                 if ( ! $this->show OR (is_array($this->show) AND ! in_array($args[0], $this->show)))
48                         return FALSE;
49
50                 // Class name
51                 $class = 'Profiler_'.ucfirst($method);
52
53                 $class = new $class();
54
55                 $this->profiles[$args[0]] = $class;
56
57                 return $class;
58         }
59
60         /**
61          * Disables the profiler for this page only.
62          * Best used when profiler is autoloaded.
63          *
64          * @return  void
65          */
66         public function disable()
67         {
68                 // Removes itself from the event queue
69                 Event::clear('system.display', array($this, 'render'));
70         }
71
72         /**
73          * Render the profiler. Output is added to the bottom of the page by default.
74          *
75          * @param   boolean  return the output if TRUE
76          * @return  void|string
77          */
78         public function render($return = FALSE)
79         {
80                 $start = microtime(TRUE);
81
82                 $get = isset($_GET['profiler']) ? explode(',', $_GET['profiler']) : array();
83                 $this->show = empty($get) ? Kohana::config('profiler.show') : $get;
84
85                 Event::run('profiler.run', $this);
86
87                 $styles = '';
88                 foreach ($this->profiles as $profile)
89                 {
90                         $styles .= $profile->styles();
91                 }
92
93                 // Don't display if there's no profiles
94                 if (empty($this->profiles))
95                         return;
96
97                 // Load the profiler view
98                 $data = array
99                 (
100                         'profiles' => $this->profiles,
101                         'styles'   => $styles,
102                         'execution_time' => microtime(TRUE) - $start
103                 );
104                 $view = new View('kohana_profiler', $data);
105
106                 // Return rendered view if $return is TRUE
107                 if ($return === TRUE)
108                         return $view->render();
109
110                 // Add profiler data to the output
111                 if (stripos(Kohana::$output, '</body>') !== FALSE)
112                 {
113                         // Closing body tag was found, insert the profiler data before it
114                         Kohana::$output = str_ireplace('</body>', $view->render().'</body>', Kohana::$output);
115                 }
116                 else
117                 {
118                         // Append the profiler data to the output
119                         Kohana::$output .= $view->render();
120                 }
121         }
122
123         /**
124          * Benchmark times and memory usage from the Benchmark library.
125          *
126          * @return  void
127          */
128         public function benchmarks()
129         {
130                 if ( ! $table = $this->table('benchmarks'))
131                         return;
132
133                 $table->add_column();
134                 $table->add_column('kp-column kp-data');
135                 $table->add_column('kp-column kp-data');
136                 $table->add_column('kp-column kp-data');
137                 $table->add_row(array('Benchmarks', 'Time', 'Count', 'Memory'), 'kp-title', 'background-color: #FFE0E0');
138
139                 $benchmarks = Benchmark::get(TRUE);
140
141                 // Moves the first benchmark (total execution time) to the end of the array
142                 $benchmarks = array_slice($benchmarks, 1) + array_slice($benchmarks, 0, 1);
143
144                 text::alternate();
145                 foreach ($benchmarks as $name => $benchmark)
146                 {
147                         // Clean unique id from system benchmark names
148                         $name = ucwords(str_replace(array('_', '-'), ' ', str_replace(SYSTEM_BENCHMARK.'_', '', $name)));
149
150                         $data = array($name, number_format($benchmark['time'], 3), $benchmark['count'], number_format($benchmark['memory'] / 1024 / 1024, 2).'MB');
151                         $class = text::alternate('', 'kp-altrow');
152
153                         if ($name == 'Total Execution')
154                                 $class = 'kp-totalrow';
155
156                         $table->add_row($data, $class);
157                 }
158         }
159
160         /**
161          * Database query benchmarks.
162          *
163          * @return  void
164          */
165         public function database()
166         {
167                 if ( ! $table = $this->table('database'))
168                         return;
169
170                 $table->add_column();
171                 $table->add_column('kp-column kp-data');
172                 $table->add_column('kp-column kp-data');
173                 $table->add_row(array('Queries', 'Time', 'Rows'), 'kp-title', 'background-color: #E0FFE0');
174
175                 $queries = Database::$benchmarks;
176
177                 text::alternate();
178                 $total_time = $total_rows = 0;
179                 foreach ($queries as $query)
180                 {
181                         $data = array($query['query'], number_format($query['time'], 3), $query['rows']);
182                         $class = text::alternate('', 'kp-altrow');
183                         $table->add_row($data, $class);
184                         $total_time += $query['time'];
185                         $total_rows += $query['rows'];
186                 }
187
188                 $data = array('Total: ' . count($queries), number_format($total_time, 3), $total_rows);
189                 $table->add_row($data, 'kp-totalrow');
190         }
191
192         /**
193          * Session data.
194          *
195          * @return  void
196          */
197         public function session()
198         {
199                 if (empty($_SESSION)) return;
200
201                 if ( ! $table = $this->table('session'))
202                         return;
203
204                 $table->add_column('kp-name');
205                 $table->add_column();
206                 $table->add_row(array('Session', 'Value'), 'kp-title', 'background-color: #CCE8FB');
207
208                 text::alternate();
209                 foreach($_SESSION as $name => $value)
210                 {
211                         if (is_object($value))
212                         {
213                                 $value = get_class($value).' [object]';
214                         }
215
216                         $data = array($name, $value);
217                         $class = text::alternate('', 'kp-altrow');
218                         $table->add_row($data, $class);
219                 }
220         }
221
222         /**
223          * POST data.
224          *
225          * @return  void
226          */
227         public function post()
228         {
229                 if (empty($_POST)) return;
230
231                 if ( ! $table = $this->table('post'))
232                         return;
233
234                 $table->add_column('kp-name');
235                 $table->add_column();
236                 $table->add_row(array('POST', 'Value'), 'kp-title', 'background-color: #E0E0FF');
237
238                 text::alternate();
239                 foreach($_POST as $name => $value)
240                 {
241                         $data = array($name, $value);
242                         $class = text::alternate('', 'kp-altrow');
243                         $table->add_row($data, $class);
244                 }
245         }
246
247         /**
248          * Cookie data.
249          *
250          * @return  void
251          */
252         public function cookies()
253         {
254                 if (empty($_COOKIE)) return;
255
256                 if ( ! $table = $this->table('cookies'))
257                         return;
258
259                 $table->add_column('kp-name');
260                 $table->add_column();
261                 $table->add_row(array('Cookies', 'Value'), 'kp-title', 'background-color: #FFF4D7');
262
263                 text::alternate();
264                 foreach($_COOKIE as $name => $value)
265                 {
266                         $data = array($name, $value);
267                         $class = text::alternate('', 'kp-altrow');
268                         $table->add_row($data, $class);
269                 }
270         }
271 }