Changed ERR_ERROR to ERR_ALERT. Added PHP5 fix for error reporting. Error handler...
[isso.git] / kernel.php
1 <?php
2 /*=====================================================================*\
3 || ################################################################### ||
4 || # Iris Studios Shared Object Framework [#]version[#]
5 || # --------------------------------------------------------------- # ||
6 || # All parts of this file are ©2003-[#]year[#] Iris Studios, Inc. No # ||
7 || # part of this file may be reproduced in any way: part or whole. # ||
8 || # --------------------------------------------------------------- # ||
9 || # ©2003 - [#]year[#] Iris Studios, Inc. | http://www.iris-studios.com # ||
10 || ################################################################### ||
11 \*=====================================================================*/
12
13 define('ERR_FATAL', E_USER_ERROR);
14 define('ERR_ALERT', E_USER_WARNING);
15 define('ERR_WARNING', E_USER_NOTICE);
16
17 if (PHP_VERSION < '4.1.0')
18 {
19 trigger_error('You need PHP version 4.1.0 or newer to run ISSO', ERR_FATAL);
20 exit;
21 }
22
23 if (PHP_VERSION > '5.0.0')
24 {
25 if (ini_get('error_reporting') & E_USER_NOTICE)
26 {
27 error_reporting(ini_get('error_reporting') - E_USER_NOTICE);
28 }
29 }
30
31 if ((bool)ini_get('register_globals') === true)
32 {
33 $superglobals = array('_GET', '_COOKIE', '_FILES', '_POST', '_SERVER', '_ENV');
34 foreach ($superglobals AS $global)
35 {
36 if (is_array(${$global}))
37 {
38 foreach (${$global} AS $_key => $_val)
39 {
40 if (isset(${$_key}))
41 {
42 unset(${$_key});
43 }
44 }
45 }
46 }
47 }
48
49 /**
50 * Iris Studios Shared Object Framework (ISSO)
51 *
52 * This framework allows a common backend to be used amongst all Iris
53 * Studios applications and can is built to be abstract and flexible.
54 * The base framework handles all loading and module management.
55 *
56 * @author Iris Studios, Inc.
57 * @copyright Copyright ©2003 - [#]year[#], Iris Studios, Inc.
58 * @version $Revision$
59 *
60 */
61 class Shared_Object_Framework
62 {
63 /**
64 * Global environment variables
65 *
66 * This is where we keep the global variables that are used within the shared framework
67 *
68 * @var version ISSO version
69 * @var sourcepath The location of the framework sources
70 * @var appath The path to the application's location
71 * @var application The name of the application that is using the framework
72 * @var debug Variable for debug mode
73 * @var debuginfo Listing of all debug notices
74 * @var modules An array of loaded framework modules
75 * @var input All input data for the system
76 * @var magicquotes Status of Magic Quotes GPC
77 */
78 var $version = '[#]version[#]';
79 var $sourcepath = '';
80 var $apppath = '';
81 var $application = '';
82 var $debug = false;
83 var $debuginfo = array();
84 var $modules = array();
85 var $input = array();
86 var $magicquotes = 0;
87
88 /**
89 * Constructor
90 */
91 function Shared_Object_Framework()
92 {
93 // error reporting
94 set_error_handler(array(&$this, '_error_handler'));
95
96 // magic quotes
97 $this->magicquotes = get_magic_quotes_gpc();
98 set_magic_quotes_runtime(0);
99
100 // start input sanitize using variable_order GP
101 $this->input = $this->_sanitize_input_recursive(array_merge($_GET, $_POST));
102
103 $this->modules['kernel'] = 'Shared Object Framework Core';
104 }
105
106 /**
107 * Prepares a path for being set as the sourcepath
108 *
109 * @param str Source path or URL
110 *
111 * @return str Prepared source path
112 */
113 function fetch_sourcepath($source)
114 {
115 if (substr($source, strlen($source) - 1) != '/')
116 {
117 $source .= '/';
118 }
119 return $source;
120 }
121
122 /**
123 * Loads a framework extension
124 *
125 * @param str Name of the framework
126 */
127 function load($framework)
128 {
129 if (!$this->is_loaded($framework))
130 {
131 $newobj = $this->locate($framework);
132 $this->$newobj['OBJ'] = new $newobj['CLASS']();
133 $GLOBALS["$newobj[OBJ]"] =& $this->$newobj['OBJ'];
134 $this->modules["$framework"] = $newobj['OBJECT'];
135 }
136 }
137
138 /**
139 * Includes a framework module. Module definitions need three variables:
140 * class, object, and obj. Class is the name of the class, object is
141 * the name human-readable name, and obj is the name that the module
142 * should be initialized as; this is used in class extensions.
143 *
144 * @param str Name of the framework
145 *
146 * @return array List of initialization variables
147 */
148 function locate($framework)
149 {
150 if ($this->sourcepath == '')
151 {
152 trigger_error('Invalid sourcepath specified', ERR_FATAL);
153 }
154
155 if (file_exists($this->sourcepath . $framework . '.php'))
156 {
157 require_once($this->sourcepath . $framework . '.php');
158 return array('CLASS' => $CLASS, 'OBJECT' => $OBJECT, 'OBJ' => $OBJ);
159 }
160 else
161 {
162 trigger_error('Could not find the framework ' . $this->sourcepath . $framework . '.php', ERR_FATAL);
163 exit;
164 }
165 }
166
167 /**
168 * Prints a list of all currently loaded framework modules
169 *
170 * @param bool Return the data as an array?
171 *
172 * @return mixed HTML output or an array of loaded modules
173 */
174 function show_modules($return = false)
175 {
176 if ($return)
177 {
178 return $this->modules;
179 }
180 else
181 {
182 $output = "\n\n<ul>\n\t<li>";
183 $output .= implode("</li>\n\t<li>", $this->modules);
184 $output .= "</li>\n</ul>\n\n";
185 $this->_message('Loaded Modules', $output, 1);
186 }
187 }
188
189 /**
190 * Verifies to see if a framework has been loaded
191 *
192 * @param str Framework name
193 *
194 * @return bool Whether or not the framework has been loaded
195 */
196 function is_loaded($framework)
197 {
198 if (isset($this->modules["$framework"]))
199 {
200 return true;
201 }
202 else
203 {
204 return false;
205 }
206 }
207
208 /**
209 * Prints an ISSO message
210 *
211 * @param str The title of the message
212 * @param str The content of the message
213 * @param int Type of message to be printed
214 * @param bool Return the output?
215 *
216 * @return mixed Output or null
217 */
218 function _message($title, $message, $type, $return = false)
219 {
220 switch ($type)
221 {
222 // Message
223 case 1:
224 $prefix = 'Message';
225 $color = '#669900';
226 $font = '#000000';
227 break;
228
229 // Warning
230 case 2:
231 $prefix = 'Warning';
232 $color = '#003399';
233 $font = '#FFFFFF';
234 break;
235
236 case 3:
237 $prefix = 'Error';
238 $color = '#990000';
239 $font = '#EFEFEF';
240 break;
241 }
242
243 $output = "\n<br />\n<table cellpadding=\"4\" cellspacing=\"1\" border=\"0\" width=\"500\" style=\"background-color: $color; font-family: Verdana, sans-serif; font-size: 12px;\">";
244 $output .= "\n<tr style=\"color: $font\">\n\t<td><strong>$prefix: $title</strong></td>\n</tr>";
245 $output .= "\n<tr style=\"background-color: #FFFFFF\">\n\t<td>$message</td>\n</tr>\n</table>\n<br />\n";
246
247 if ($return)
248 {
249 return $output;
250 }
251 else
252 {
253 print($output);
254 }
255 }
256
257 /**
258 * Custom error handler for ISSO
259 *
260 * @param int Error number
261 * @param str Error message string
262 * @param str File that contains the error
263 * @param str The line number of the error
264 * @param str The active symbol table at which point the error occurred
265 */
266 function _error_handler($errno, $errstr, $errfile, $errline)
267 {
268 switch ($errno)
269 {
270 // Fatal
271 case ERR_FATAL:
272 $title = 'Fatal';
273 if (!(ini_get('error_reporting') & ERR_FATAL))
274 {
275 return;
276 }
277 break;
278
279 // Error
280 case ERR_ALERT:
281 $title = 'Alert';
282 if (!(ini_get('error_reporting') & ERR_ALERT))
283 {
284 return;
285 }
286 break;
287
288 // Warning
289 case ERR_WARNING:
290 default:
291 $title = 'Warning';
292 if (!(ini_get('error_reporting') & ERR_WARNING))
293 {
294 return;
295 }
296 break;
297 }
298
299 $errstr .= " in <strong>$errfile</strong> on line <strong>$errline</strong>";
300
301 $this->_message($title, $errstr, 3);
302
303 if ($errno == ERR_FATAL)
304 {
305 exit;
306 }
307 }
308
309 /**
310 * Logs a debug message for verbose output
311 *
312 * @param str Message
313 */
314 function debug($message)
315 {
316 if ($this->debug)
317 {
318 $this->debuginfo[] = $message;
319 }
320 }
321
322 /**
323 * Recursive XSS cleaner
324 *
325 * @param mixed Unsanitized REQUEST data
326 *
327 * @return mixed Sanitized data
328 */
329 function _sanitize_input_recursive($data)
330 {
331 foreach($data AS $key => $value)
332 {
333 if (is_array($value))
334 {
335 $data["$key"] = $this->_sanitize_input_recursive($value);
336 }
337 else
338 {
339 $data["$key"] = $this->sanitize($value);
340 }
341 }
342 return $data;
343 }
344
345 /**
346 * Simple way to protect against HTML attacks with Unicode support
347 *
348 * @param str Unsanitzed text
349 *
350 * @return str Properly protected text that only encodes potential threats
351 */
352 function sanitize($text)
353 {
354 if ($this->magicquotes)
355 {
356 return str_replace(array('<', '>', '\"', '"'), array('&lt;', '&gt;', '&quot;', '&quot;'), $text);
357 }
358 else
359 {
360 return str_replace(array('<', '>', '"'), array('&lt;', '&gt;', '&quot;'), $text);
361 }
362 }
363
364 /**
365 * Takes text that has been processed for HTML and unsanitizes it
366 *
367 * @param str Text that needs to be turned back into HTML
368 *
369 * @return str Unsanitized text
370 */
371 function unsanitize($text)
372 {
373 if ($this->magicquotes)
374 {
375 return str_replace(array('&lt;', '&gt;', '&quot;'), array('<', '>', '\"'), $text);
376 }
377 else
378 {
379 return str_replace(array('&lt;', '&gt;', '&quot;'), array('<', '>', '"'), $text);
380 }
381 }
382
383 /**
384 * Smart addslashes() that only applies itself it the Magic Quotes GPC is off
385 *
386 * @param str Some string
387 *
388 * @return str String that has slashes added
389 */
390 function escape($str)
391 {
392 global $_isso;
393
394 if ($this->magicquotes)
395 {
396 return $str;
397 }
398 else
399 {
400 if (isset($_isso->db))
401 {
402 if (is_resource($_isso->db->link_id))
403 {
404 return $_isso->db->escape_string($str);
405 }
406 else
407 {
408 return addslashes($str);
409 }
410 }
411 else
412 {
413 return addslashes($str);
414 }
415 }
416 }
417 }
418
419 /**
420 * Global callback used for module calls back to the kernel
421 */
422 $_isso = new Shared_Object_Framework();
423
424 /**
425 * Wrapper for ternary operator that has to be in the global scope
426 *
427 * @param expr Expression
428 * @param mixed If the expression is true
429 * @param mixed If the expression is false
430 *
431 * @return mixed True or false data
432 */
433 function iff($condition, $iftrue, $iffalse = null)
434 {
435 return ($condition) ? ($iftrue) : ($iffalse);
436 }
437
438 /*=====================================================================*\
439 || ###################################################################
440 || # $HeadURL$
441 || # $Id$
442 || ###################################################################
443 \*=====================================================================*/
444 ?>