Remove file execution permission.
[living-lab-site.git] / system / libraries / Profiler.php
1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2 /**
3  * CodeIgniter
4  *
5  * An open source application development framework for PHP 5.1.6 or newer
6  *
7  * @package             CodeIgniter
8  * @author              ExpressionEngine Dev Team
9  * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc.
10  * @license             http://codeigniter.com/user_guide/license.html
11  * @link                http://codeigniter.com
12  * @since               Version 1.0
13  * @filesource
14  */
15
16 // ------------------------------------------------------------------------
17
18 /**
19  * CodeIgniter Profiler Class
20  *
21  * This class enables you to display benchmark, query, and other data
22  * in order to help with debugging and optimization.
23  *
24  * Note: At some point it would be good to move all the HTML in this class
25  * into a set of template files in order to allow customization.
26  *
27  * @package             CodeIgniter
28  * @subpackage  Libraries
29  * @category    Libraries
30  * @author              ExpressionEngine Dev Team
31  * @link                http://codeigniter.com/user_guide/general/profiling.html
32  */
33 class CI_Profiler {
34
35         var $CI;
36
37         protected $_available_sections = array(
38                                                                                 'benchmarks',
39                                                                                 'get',
40                                                                                 'memory_usage',
41                                                                                 'post',
42                                                                                 'uri_string',
43                                                                                 'controller_info',
44                                                                                 'queries',
45                                                                                 'http_headers',
46                                                                                 'config'
47                                                                                 );
48
49         public function __construct($config = array())
50         {
51                 $this->CI =& get_instance();
52                 $this->CI->load->language('profiler');
53
54                 // default all sections to display
55                 foreach ($this->_available_sections as $section)
56                 {
57                         if ( ! isset($config[$section]))
58                         {
59                                 $this->_compile_{$section} = TRUE;
60                         }
61                 }
62
63                 $this->set_sections($config);
64         }
65
66         // --------------------------------------------------------------------
67
68         /**
69          * Set Sections
70          *
71          * Sets the private _compile_* properties to enable/disable Profiler sections
72          *
73          * @param       mixed
74          * @return      void
75          */
76         public function set_sections($config)
77         {
78                 foreach ($config as $method => $enable)
79                 {
80                         if (in_array($method, $this->_available_sections))
81                         {
82                                 $this->_compile_{$method} = ($enable !== FALSE) ? TRUE : FALSE;
83                         }
84                 }
85         }
86
87         // --------------------------------------------------------------------
88
89         /**
90          * Auto Profiler
91          *
92          * This function cycles through the entire array of mark points and
93          * matches any two points that are named identically (ending in "_start"
94          * and "_end" respectively).  It then compiles the execution times for
95          * all points and returns it as an array
96          *
97          * @return      array
98          */
99         protected function _compile_benchmarks()
100         {
101                 $profile = array();
102                 foreach ($this->CI->benchmark->marker as $key => $val)
103                 {
104                         // We match the "end" marker so that the list ends
105                         // up in the order that it was defined
106                         if (preg_match("/(.+?)_end/i", $key, $match))
107                         {
108                                 if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start']))
109                                 {
110                                         $profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);
111                                 }
112                         }
113                 }
114
115                 // Build a table containing the profile data.
116                 // Note: At some point we should turn this into a template that can
117                 // be modified.  We also might want to make this data available to be logged
118
119                 $output  = "\n\n";
120                 $output .= '<fieldset id="ci_profiler_benchmarks" style="border:1px solid #900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
121                 $output .= "\n";
122                 $output .= '<legend style="color:#900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks').'&nbsp;&nbsp;</legend>';
123                 $output .= "\n";
124                 $output .= "\n\n<table style='width:100%'>\n";
125
126                 foreach ($profile as $key => $val)
127                 {
128                         $key = ucwords(str_replace(array('_', '-'), ' ', $key));
129                         $output .= "<tr><td style='padding:5px;width:50%;color:#000;font-weight:bold;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td style='padding:5px;width:50%;color:#900;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
130                 }
131
132                 $output .= "</table>\n";
133                 $output .= "</fieldset>";
134
135                 return $output;
136         }
137
138         // --------------------------------------------------------------------
139
140         /**
141          * Compile Queries
142          *
143          * @return      string
144          */
145         protected function _compile_queries()
146         {
147                 $dbs = array();
148
149                 // Let's determine which databases are currently connected to
150                 foreach (get_object_vars($this->CI) as $CI_object)
151                 {
152                         if (is_object($CI_object) && is_subclass_of(get_class($CI_object), 'CI_DB') )
153                         {
154                                 $dbs[] = $CI_object;
155                         }
156                 }
157
158                 if (count($dbs) == 0)
159                 {
160                         $output  = "\n\n";
161                         $output .= '<fieldset id="ci_profiler_queries" style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
162                         $output .= "\n";
163                         $output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>';
164                         $output .= "\n";
165                         $output .= "\n\n<table style='border:none; width:100%'>\n";
166                         $output .="<tr><td style='width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px'>".$this->CI->lang->line('profiler_no_db')."</td></tr>\n";
167                         $output .= "</table>\n";
168                         $output .= "</fieldset>";
169
170                         return $output;
171                 }
172
173                 // Load the text helper so we can highlight the SQL
174                 $this->CI->load->helper('text');
175
176                 // Key words we want bolded
177                 $highlight = array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT&nbsp;JOIN', 'ORDER&nbsp;BY', 'GROUP&nbsp;BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR&nbsp;', 'HAVING', 'OFFSET', 'NOT&nbsp;IN', 'IN', 'LIKE', 'NOT&nbsp;LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')');
178
179                 $output  = "\n\n";
180
181                 foreach ($dbs as $db)
182                 {
183                         $output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
184                         $output .= "\n";
185                         $output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_database').':&nbsp; '.$db->database.'&nbsp;&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').': '.count($db->queries).'&nbsp;&nbsp;&nbsp;</legend>';
186                         $output .= "\n";
187                         $output .= "\n\n<table style='width:100%;'>\n";
188
189                         if (count($db->queries) == 0)
190                         {
191                                 $output .= "<tr><td style='width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;'>".$this->CI->lang->line('profiler_no_queries')."</td></tr>\n";
192                         }
193                         else
194                         {
195                                 foreach ($db->queries as $key => $val)
196                                 {
197                                         $time = number_format($db->query_times[$key], 4);
198
199                                         $val = highlight_code($val, ENT_QUOTES);
200
201                                         foreach ($highlight as $bold)
202                                         {
203                                                 $val = str_replace($bold, '<strong>'.$bold.'</strong>', $val);
204                                         }
205
206                                         $output .= "<tr><td style='padding:5px; vertical-align: top;width:1%;color:#900;font-weight:normal;background-color:#ddd;'>".$time."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
207                                 }
208                         }
209
210                         $output .= "</table>\n";
211                         $output .= "</fieldset>";
212
213                 }
214
215                 return $output;
216         }
217
218
219         // --------------------------------------------------------------------
220
221         /**
222          * Compile $_GET Data
223          *
224          * @return      string
225          */
226         protected function _compile_get()
227         {
228                 $output  = "\n\n";
229                 $output .= '<fieldset id="ci_profiler_get" style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
230                 $output .= "\n";
231                 $output .= '<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data').'&nbsp;&nbsp;</legend>';
232                 $output .= "\n";
233
234                 if (count($_GET) == 0)
235                 {
236                         $output .= "<div style='color:#cd6e00;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_get')."</div>";
237                 }
238                 else
239                 {
240                         $output .= "\n\n<table style='width:100%; border:none'>\n";
241
242                         foreach ($_GET as $key => $val)
243                         {
244                                 if ( ! is_numeric($key))
245                                 {
246                                         $key = "'".$key."'";
247                                 }
248
249                                 $output .= "<tr><td style='width:50%;color:#000;background-color:#ddd;padding:5px'>&#36;_GET[".$key."]&nbsp;&nbsp; </td><td style='width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;'>";
250                                 if (is_array($val))
251                                 {
252                                         $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";
253                                 }
254                                 else
255                                 {
256                                         $output .= htmlspecialchars(stripslashes($val));
257                                 }
258                                 $output .= "</td></tr>\n";
259                         }
260
261                         $output .= "</table>\n";
262                 }
263                 $output .= "</fieldset>";
264
265                 return $output;
266         }
267
268         // --------------------------------------------------------------------
269
270         /**
271          * Compile $_POST Data
272          *
273          * @return      string
274          */
275         protected function _compile_post()
276         {
277                 $output  = "\n\n";
278                 $output .= '<fieldset id="ci_profiler_post" style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
279                 $output .= "\n";
280                 $output .= '<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data').'&nbsp;&nbsp;</legend>';
281                 $output .= "\n";
282
283                 if (count($_POST) == 0)
284                 {
285                         $output .= "<div style='color:#009900;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_post')."</div>";
286                 }
287                 else
288                 {
289                         $output .= "\n\n<table style='width:100%'>\n";
290
291                         foreach ($_POST as $key => $val)
292                         {
293                                 if ( ! is_numeric($key))
294                                 {
295                                         $key = "'".$key."'";
296                                 }
297
298                                 $output .= "<tr><td style='width:50%;padding:5px;color:#000;background-color:#ddd;'>&#36;_POST[".$key."]&nbsp;&nbsp; </td><td style='width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;'>";
299                                 if (is_array($val))
300                                 {
301                                         $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, TRUE))) . "</pre>";
302                                 }
303                                 else
304                                 {
305                                         $output .= htmlspecialchars(stripslashes($val));
306                                 }
307                                 $output .= "</td></tr>\n";
308                         }
309
310                         $output .= "</table>\n";
311                 }
312                 $output .= "</fieldset>";
313
314                 return $output;
315         }
316
317         // --------------------------------------------------------------------
318
319         /**
320          * Show query string
321          *
322          * @return      string
323          */
324         protected function _compile_uri_string()
325         {
326                 $output  = "\n\n";
327                 $output .= '<fieldset id="ci_profiler_uri_string" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
328                 $output .= "\n";
329                 $output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string').'&nbsp;&nbsp;</legend>';
330                 $output .= "\n";
331
332                 if ($this->CI->uri->uri_string == '')
333                 {
334                         $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_uri')."</div>";
335                 }
336                 else
337                 {
338                         $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->uri->uri_string."</div>";
339                 }
340
341                 $output .= "</fieldset>";
342
343                 return $output;
344         }
345
346         // --------------------------------------------------------------------
347
348         /**
349          * Show the controller and function that were called
350          *
351          * @return      string
352          */
353         protected function _compile_controller_info()
354         {
355                 $output  = "\n\n";
356                 $output .= '<fieldset id="ci_profiler_controller_info" style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
357                 $output .= "\n";
358                 $output .= '<legend style="color:#995300;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_controller_info').'&nbsp;&nbsp;</legend>';
359                 $output .= "\n";
360
361                 $output .= "<div style='color:#995300;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->router->fetch_class()."/".$this->CI->router->fetch_method()."</div>";
362
363                 $output .= "</fieldset>";
364
365                 return $output;
366         }
367
368         // --------------------------------------------------------------------
369
370         /**
371          * Compile memory usage
372          *
373          * Display total used memory
374          *
375          * @return      string
376          */
377         protected function _compile_memory_usage()
378         {
379                 $output  = "\n\n";
380                 $output .= '<fieldset id="ci_profiler_memory_usage" style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
381                 $output .= "\n";
382                 $output .= '<legend style="color:#5a0099;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage').'&nbsp;&nbsp;</legend>';
383                 $output .= "\n";
384
385                 if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '')
386                 {
387                         $output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".number_format($usage).' bytes</div>';
388                 }
389                 else
390                 {
391                         $output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_memory_usage')."</div>";
392                 }
393
394                 $output .= "</fieldset>";
395
396                 return $output;
397         }
398
399         // --------------------------------------------------------------------
400
401         /**
402          * Compile header information
403          *
404          * Lists HTTP headers
405          *
406          * @return      string
407          */
408         protected function _compile_http_headers()
409         {
410                 $output  = "\n\n";
411                 $output .= '<fieldset id="ci_profiler_http_headers" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
412                 $output .= "\n";
413                 $output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_headers').'&nbsp;&nbsp;</legend>';
414                 $output .= "\n";
415
416                 $output .= "\n\n<table style='width:100%'>\n";
417
418                 foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR') as $header)
419                 {
420                         $val = (isset($_SERVER[$header])) ? $_SERVER[$header] : '';
421                         $output .= "<tr><td style='vertical-align: top;width:50%;padding:5px;color:#900;background-color:#ddd;'>".$header."&nbsp;&nbsp;</td><td style='width:50%;padding:5px;color:#000;background-color:#ddd;'>".$val."</td></tr>\n";
422                 }
423
424                 $output .= "</table>\n";
425                 $output .= "</fieldset>";
426
427                 return $output;
428         }
429
430         // --------------------------------------------------------------------
431
432         /**
433          * Compile config information
434          *
435          * Lists developer config variables
436          *
437          * @return      string
438          */
439         protected function _compile_config()
440         {
441                 $output  = "\n\n";
442                 $output .= '<fieldset id="ci_profiler_config" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
443                 $output .= "\n";
444                 $output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_config').'&nbsp;&nbsp;</legend>';
445                 $output .= "\n";
446
447                 $output .= "\n\n<table style='width:100%'>\n";
448
449                 foreach ($this->CI->config->config as $config=>$val)
450                 {
451                         if (is_array($val))
452                         {
453                                 $val = print_r($val, TRUE);
454                         }
455
456                         $output .= "<tr><td style='padding:5px; vertical-align: top;color:#900;background-color:#ddd;'>".$config."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;background-color:#ddd;'>".htmlspecialchars($val)."</td></tr>\n";
457                 }
458
459                 $output .= "</table>\n";
460                 $output .= "</fieldset>";
461
462                 return $output;
463         }
464
465         // --------------------------------------------------------------------
466
467         /**
468          * Run the Profiler
469          *
470          * @return      string
471          */
472         public function run()
473         {
474                 $output = "<div id='codeigniter_profiler' style='clear:both;background-color:#fff;padding:10px;'>";
475                 $fields_displayed = 0;
476
477                 foreach ($this->_available_sections as $section)
478                 {
479                         if ($this->_compile_{$section} !== FALSE)
480                         {
481                                 $func = "_compile_{$section}";
482                                 $output .= $this->{$func}();
483                                 $fields_displayed++;
484                         }
485                 }
486
487                 if ($fields_displayed == 0)
488                 {
489                         $output .= '<p style="border:1px solid #5a0099;padding:10px;margin:20px 0;background-color:#eee">'.$this->CI->lang->line('profiler_no_profiles').'</p>';
490                 }
491
492                 $output .= '</div>';
493
494                 return $output;
495         }
496
497 }
498
499 // END CI_Profiler class
500
501 /* End of file Profiler.php */
502 /* Location: ./system/libraries/Profiler.php */