Removing the error_reporting shuffling that we did previously
[isso.git] / kernel.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Blue Static ISSO Framework [#]issoversion[#]
5 || # Copyright ©2002-[#]year[#] Blue Static
6 || #
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version [#]gpl[#] of the License.
10 || #
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 || # more details.
15 || #
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
21
22 /**
23 * Blue Static ISSO Framework Kernel
24 * kernel.php
25 *
26 * @package ISSO
27 */
28
29 if (!function_exists('stripos'))
30 {
31 trigger_error('You need PHP version 5.0.0 or newer to run ISSO', E_USER_ERROR);
32 exit;
33 }
34
35 if ((bool)ini_get('register_globals') === true)
36 {
37 $superglobals = array('_GET', '_COOKIE', '_FILES', '_POST', '_SERVER', '_ENV');
38 foreach ($superglobals AS $global)
39 {
40 if (is_array(${$global}))
41 {
42 foreach (${$global} AS $_key => $_val)
43 {
44 if (isset(${$_key}))
45 {
46 unset(${$_key});
47 }
48 }
49 }
50 }
51 }
52
53 /**
54 * Yes, required
55 */
56 define('REQ_YES', 1);
57
58 /**
59 * No, not required
60 */
61 define('REQ_NO', 0);
62
63 /**
64 * Blue Static ISSO Framework (ISSO)
65 *
66 * This framework allows a common backend to be used amongst all Blue
67 * Static applications and is built to be abstract and flexible.
68 * The base framework handles all loading and module management.
69 *
70 * Constants:
71 * ISSO_MT_START - Define the microtime() value at the top of your
72 * script and this will calculate the total execution
73 * time
74 * SVN - Place SVN keywords (like $Id) to display the information on output
75 *
76 * @author Blue Static
77 * @copyright Copyright ©2002 - [#]year[#], Blue Static
78 * @version $Revision$
79 * @package ISSO
80 *
81 */
82 class ISSO
83 {
84 /**
85 * ISSO version
86 * @var string
87 */
88 private $version = '[#]issoversion[#]';
89
90 /**
91 * List of loaded modules
92 * @var array
93 */
94 private $modules = array();
95
96 // ###################################################################
97 /**
98 * Constructor
99 */
100 public function __construct()
101 {
102 $GLOBALS['isso:callback'] = null;
103
104 // error reporting
105 set_error_handler(array(&$this, '_error_handler'));
106 }
107
108 // ###################################################################
109 /**
110 * Prints a list of all currently loaded framework modules
111 *
112 * @param bool Return the data as an array?
113 *
114 * @return mixed HTML output or an array of loaded modules
115 */
116 public function show_modules($return = false)
117 {
118 $modules = array();
119 foreach ($this->modules AS $object)
120 {
121 $module = get_class($object);
122 if (method_exists($object, 'init_as_package') AND in_array($module, $modules))
123 {
124 $module = $object->init_as_package() . " - ($module)";
125 }
126
127 $modules[] = $module;
128 }
129
130 if ($return)
131 {
132 return $modules;
133 }
134 else
135 {
136 $output = "\n\n<ul>\n\t<li>";
137 $output .= implode("</li>\n\t<li>", $modules);
138 $output .= "</li>\n</ul>\n\n";
139 $this->message('Loaded Modules', $output, 1);
140 }
141 }
142
143 // ###################################################################
144 /**
145 * Prints an ISSO message
146 *
147 * @param string The title of the message
148 * @param string The content of the message
149 * @param integer Type of message to be printed
150 * @param bool Return the output?
151 * @param bool Show the debug stack?
152 * @param integer Message width
153 *
154 * @return mixed Output or null
155 */
156 public function message($title, $message, $type, $return = false, $stack = true, $width = 500)
157 {
158 switch ($type)
159 {
160 // Message
161 case 1:
162 $prefix = 'Message';
163 $color = '#669900';
164 $font = '#000000';
165 break;
166
167 // Warning
168 case 2:
169 $prefix = 'Warning';
170 $color = '#003399';
171 $font = '#FFFFFF';
172 break;
173
174 case 3:
175 $prefix = 'Error';
176 $color = '#990000';
177 $font = '#EFEFEF';
178 break;
179 }
180
181 $backtrace = debug_backtrace();
182 array_shift($backtrace);
183
184 if (isset($backtrace[0]) AND $backtrace[0]['function'] == '_error_handler')
185 {
186 array_shift($backtrace);
187 }
188
189 $trace = $this->format_debug_trace($backtrace);
190
191 $output = "\n<br />\n<table cellpadding=\"4\" cellspacing=\"1\" border=\"0\" width=\"$width\" style=\"background-color: $color; color: black; font-family: Verdana, sans-serif; font-size: 12px;\">";
192 $output .= "\n<tr style=\"color: $font; text-align: left\">\n\t<td><strong>$prefix: $title</strong></td>\n</tr>";
193 $output .= "\n<tr style=\"background-color: #FFFFFF; text-align: left\">\n\t<td>$message</td>\n</tr>";
194 $output .= (($stack AND $GLOBALS['isso:callback']->debug) ? "\n<tr style=\"background-color: #FFFFFF; text-align: left\">\n\t<td><strong>Debug Stack:</strong> <pre>" . implode("\n", $trace) . "</pre></td>\n</tr>" : '');
195 $output .= "\n</table>\n<br />\n";
196
197 if ($return)
198 {
199 return $output;
200 }
201 else
202 {
203 print($output);
204 }
205 }
206
207 // ###################################################################
208 /**
209 * Prepares a debug_backtrace() array for output to the browser by
210 * compressing the array into visible text
211 *
212 * @param array debug_backtrace() array
213 *
214 * @return array Formatted trace output
215 */
216 public function format_debug_trace($backtrace)
217 {
218 $trace = array();
219 foreach ($backtrace AS $i => $step)
220 {
221 $args = '';
222 $file = $step['file'] . ':' . $step['line'];
223 $funct = (isset($step['class']) ? $step['class'] . '::' . $step['function'] : $step['function']);
224
225 if (isset($step['args']) AND is_array($step['args']))
226 {
227 // we need to do this so we don't get "Array to string conversion" notices
228 foreach ($step['args'] AS $id => $arg)
229 {
230 if (is_array($arg))
231 {
232 $step['args']["$id"] = 'Array';
233 }
234 }
235 $args = implode(', ', $step['args']);
236 }
237
238 $trace[] = "#$i $funct($args) called at [$file]";
239 }
240
241 return $trace;
242 }
243
244 // ###################################################################
245 /**
246 * Custom error handler for ISSO; only handle E_WARNING, E_NOTICE,
247 * E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE
248 *
249 * @param integer Error number
250 * @param string Error message string
251 * @param string File that contains the error
252 * @param string The line number of the error
253 * @param string The active symbol table at which point the error occurred
254 */
255 public function _error_handler($errno, $errstr, $errfile, $errline, $errcontext)
256 {
257 $level = ini_get('error_reporting');
258
259 switch ($errno)
260 {
261 // Fatal
262 case E_USER_ERROR:
263 $title = 'Fatal';
264 $mode = 3;
265 if (!($level & E_USER_ERROR))
266 {
267 return;
268 }
269 break;
270
271 // Error
272 case E_USER_WARNING:
273 case E_WARNING:
274 $title = 'Warning';
275 $mode = 2;
276 if (! (($level & E_USER_WARNING) AND ($level & E_WARNING)) )
277 {
278 return;
279 }
280 break;
281
282 // Warning
283 case E_USER_NOTICE:
284 case E_NOTICE:
285 default:
286 $title = 'Notice';
287 $mode = 1;
288 if (! (($level & E_USER_NOTICE) AND ($level & E_NOTICE)) )
289 {
290 return;
291 }
292 break;
293 }
294
295 $errstr .= " in <strong>$errfile</strong> on line <strong>$errline</strong>";
296
297 $errstr = str_replace(array(getcwd(), dirname(getcwd())), '', $errstr);
298
299 $this->message($title, $errstr, $mode);
300
301 if ($errno == E_USER_ERROR)
302 {
303 exit;
304 }
305 }
306
307 // ###################################################################
308 /**
309 * Creates a table that explains the error reporting levels and their
310 * state
311 */
312 public function explain_error_reporting()
313 {
314 $levels = array(
315 'E_ERROR' => E_ERROR,
316 'E_WARNING' => E_WARNING,
317 'E_PARSE' => E_PARSE,
318 'E_NOTICE' => E_NOTICE,
319 'E_CORE_ERROR' => E_CORE_ERROR,
320 'E_CORE_WARNING' => E_CORE_WARNING,
321 'E_COMPILE_ERROR' => E_COMPILE_ERROR,
322 'E_COMPILE_WARNING' => E_COMPILE_WARNING,
323 'E_USER_ERROR' => E_USER_ERROR,
324 'E_USER_WARNING' => E_USER_WARNING,
325 'E_USER_NOTICE' => E_USER_NOTICE,
326 'E_ALL' => E_ALL,
327 'E_STRICT' => E_STRICT
328 );
329
330 $table = '<table cellspacing="0" cellpadding="2" border="0">';
331
332 foreach ($levels AS $name => $value)
333 {
334 $table .= '
335 <tr>
336 <td>' . $name . '</td>
337 <td>' . (ini_get('error_reporting') & $value) . '</td>
338 </tr>';
339 }
340
341 $table .= '
342 </table>';
343
344 $this->message('Error Reporting', $table, 1);
345 }
346
347 // ###################################################################
348 /**
349 * Constructs a debug information box that contains various debugging
350 * information points
351 *
352 * @param bool Show template information?
353 *
354 * @return string Debugging block
355 */
356 public function construct_debug_block($dotemplates)
357 {
358 $debug = '';
359
360 if ($this->debug)
361 {
362 $debug = "\n<ul>";
363
364 // templates
365 if ($dotemplates)
366 {
367 $optlist = array();
368 $usage = array();
369 foreach ($this->modules['template']->usage AS $name => $count)
370 {
371 if (in_array($name, $this->modules['template']->uncached))
372 {
373 $optlist[] = $name . '[' . $count . ']';
374 }
375 $usage[] = $name . " ($count)";
376 }
377
378 $sizeof = sizeof($this->modules['template']->uncached);
379 if ($sizeof > 0)
380 {
381 $debug .= "\n\t<li><strong style=\"color: red\">Uncached Template(s):</strong> $sizeof ( " . implode(' &nbsp; ', $optlist) . " )</li>";
382 }
383 }
384
385 // source control
386 $scinfo = 'Not Under Source Control';
387 if (defined('SVN'))
388 {
389 $scinfo = constant('SVN');
390
391 if (preg_match('#\$Id:?\s*\$#', $scinfo))
392 {
393 $scinfo = 'Not Under Source Control';
394 }
395 else
396 {
397 $scinfo = preg_replace('#\$' . '(Head)?URL: (.+?) \$#e', "end(explode('/', '\\2'))", $scinfo);
398 $scinfo = preg_replace('#\$' . '(LastModified)?Revision: (.+?) \$#', 'SVN \\2', $scinfo);
399 $scinfo = preg_replace('#\$' . 'Id: (.+?) ([0-9].+?) [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.+?) (.+?) \$#', '\\1 - SVN \\2', $scinfo);
400 }
401 }
402
403 $scinfo = trim($scinfo);
404 $debug .= "\n\t<li><strong>Source Control:</strong> $scinfo</li>";
405
406 // query information
407 if (is_object($this->modules[ISSO_DB_LAYER]))
408 {
409 $debug .= "\n\t<li><strong>Total Queries:</strong> " . sizeof($this->modules[ISSO_DB_LAYER]->history) . " (<a href=\"" . $this->sanitize($_SERVER['REQUEST_URI']) . ((strpos($_SERVER['REQUEST_URI'], '?') !== false) ? '&amp;query=1' : '?query=1') . "\">?</a>)</li>";
410 }
411
412 // total execution time
413 if (defined('ISSO_MT_START'))
414 {
415 $this->load('functions', 'functions');
416 $debug .= "\n\t<li><strong>Total Execution Time:</strong> " . round($this->modules['functions']->fetch_microtime_diff(ISSO_MT_START), 10) . "</li>";
417 }
418
419 // debug notices
420 $debug .= "\n\t<li>\n\t\t<select>\n\t\t\t<option>Debug Notices (" . sizeof($this->debuginfo) . ")</option>";
421 foreach ((array)$this->debuginfo AS $msg)
422 {
423 $debug .= "\n\t\t\t<option>--- $msg</option>";
424 }
425 $debug .= "\n\t\t</select>\n\t</li>";
426
427 // loaded modules
428 $modules = $this->show_modules(true);
429 $debug .= "\n\t<li>\n\t\t<select>\n\t\t\t<option>Loaded Modules (" . sizeof($modules) . ")</option>";
430 foreach ($modules AS $mod)
431 {
432 $debug .= "\n\t\t\t<option>--- $mod</option>";
433 }
434 $debug .= "\n\t\t</select>\n\t</li>";
435
436 // template usage
437 if ($dotemplates)
438 {
439 $debug .= "\n\t<li>\n\t\t<select>\n\t\t\t<option>Template Usage (" . array_sum($this->modules['template']->usage) . ")</option>";
440 foreach ($usage AS $tpl)
441 {
442 $debug .= "\n\t\t\t<option>--- $tpl</option>";
443 }
444 $debug .= "\n\t\t</select>\n\t</li>";
445 }
446
447 $debug .= "\n</ul>";
448
449 $debug = "\n\n<!-- dev debug -->\n<div align=\"center\">\n\n<hr />\n" . $this->message('Debug Information', $debug, 1, true, false) . "\n</div>\n<!-- / dev debug -->\n\n";
450 }
451
452 return $debug;
453 }
454 }
455
456 /*=====================================================================*\
457 || ###################################################################
458 || # $HeadURL$
459 || # $Id$
460 || ###################################################################
461 \*=====================================================================*/
462 ?>