Adding the results of testing with PHP5
[isso.git] / Register.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Blue Static ISSO Framework
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 * ISSO Registry (Register.php)
24 *
25 * Constants:
26 * ISSO_MT_START - Define the microtime() value at the top of your
27 * script and this will calculate the total execution
28 * time
29 * SVN - Place SVN $Id keyword to get SVN revision information on output
30 *
31 * @package ISSO
32 */
33
34 // we need PHP5 to run
35 if (!function_exists('stripos'))
36 {
37 trigger_error('You need PHP version 5.0.0 or newer to run ISSO', E_USER_ERROR);
38 exit;
39 }
40
41 // get rid of register_globals
42 if ((bool)ini_get('register_globals') === true)
43 {
44 $superglobals = array('_GET', '_COOKIE', '_FILES', '_POST', '_SERVER', '_ENV');
45 foreach ($superglobals AS $global)
46 {
47 if (is_array(${$global}))
48 {
49 foreach (${$global} AS $_key => $_val)
50 {
51 if (isset(${$_key}))
52 {
53 unset(${$_key});
54 }
55 }
56 }
57 }
58 }
59
60 require_once('ISSO/Functions.php');
61
62 /**
63 * Register Class
64 *
65 * This is an ISSO registry class. It holds all of the ISSO system variables as well
66 * as serving as an object registry that is avaliable in the global scope to prevent
67 * globalization of variables. There can only be one instance of this existing
68 * at any given time.
69 *
70 * @author Blue Static
71 * @copyright Copyright ©2002 - [#]year[#], Blue Static
72 * @version $Revision$
73 * @package ISSO
74 *
75 */
76 class BSRegister
77 {
78 /**
79 * Instance of this class
80 * @var object
81 */
82 private static $instance;
83
84 /**
85 * Application name
86 * @var string
87 */
88 private $application = 'Unknown ISSO Project';
89
90 /**
91 * Application path
92 * @var string
93 */
94 private $appPath;
95
96 /**
97 * Application version
98 * @var string
99 */
100 private $appVersion;
101
102 /**
103 * Web path
104 * @var string
105 */
106 private $webPath;
107
108 /**
109 * Debug mode?
110 * @var bool
111 */
112 private $debug = false;
113
114 /**
115 * The master registry list
116 * @var array
117 */
118 private $registry = array();
119
120 /**
121 * An array of debug messages
122 * @var array
123 */
124 private $debugInfo = array();
125
126 // ###################################################################
127 /**
128 * Constructor
129 */
130 private function __construct() {}
131
132 // ###################################################################
133 /**
134 * Returns the single instance of the register
135 *
136 * @param string A string param
137 *
138 * @return object BSRegister instance
139 */
140 private static function _Instance()
141 {
142 if (!self::$instance)
143 {
144 self::$instance = new BSRegister();
145 set_error_handler(array(self::$instance, '_errorHandler'));
146 }
147 return self::$instance;
148 }
149
150 // ###################################################################
151 /**
152 * Sets the application name
153 *
154 * @param string Application name
155 */
156 public static function SetApplication($name)
157 {
158 self::_Instance()->application = $name;
159 }
160
161 // ###################################################################
162 /**
163 * Gets the application name
164 *
165 * @return string Application name
166 */
167 public static function GetApplication()
168 {
169 return self::_Instance()->application;
170 }
171
172 // ###################################################################
173 /**
174 * Sets the application's working path
175 *
176 * @param string Path
177 */
178 public static function SetAppPath($path)
179 {
180 self::_Instance()->appPath = BSFunctions::FetchSourcePath($path);
181 }
182
183 // ###################################################################
184 /**
185 * Returns the path to the application
186 *
187 * @return string Application path
188 */
189 public static function GetAppPath()
190 {
191 return self::_Instance()->appPath;
192 }
193
194 // ###################################################################
195 /**
196 * Sets the application version
197 *
198 * @param string Application version
199 */
200 public static function SetAppVersion($vers)
201 {
202 self::_Instance()->appVersion = $vers;
203 }
204
205 // ###################################################################
206 /**
207 * Gets the application version
208 *
209 * @return string Application version
210 */
211 public static function GetAppVersion()
212 {
213 return self::_Instance()->appVersion;
214 }
215
216 // ###################################################################
217 /**
218 * Sets the application's web path, which is the full path from the
219 * server's web root
220 *
221 * @param string Path
222 */
223 public static function SetWebPath($path)
224 {
225 self::_Instance()->webPath = BSFunctions::FetchSourcePath($path);
226 }
227
228 // ###################################################################
229 /**
230 * Returns the web path to the application
231 *
232 * @return string Application's web path
233 */
234 public static function GetWebPath()
235 {
236 return self::_Instance()->webPath;
237 }
238
239 // ###################################################################
240 /**
241 * Sets the debug state
242 *
243 * @param bool Debug mode on?
244 */
245 public static function SetDebug($debug)
246 {
247 self::_Instance()->debug = $debug;
248 }
249
250 // ###################################################################
251 /**
252 * Gets the debug mode state
253 *
254 * @return bool Debug mode on?
255 */
256 public static function GetDebug()
257 {
258 return self::_Instance()->debug;
259 }
260
261 // ###################################################################
262 /**
263 * Registers a value in the master registry. You cannot overwrite
264 * values. You must first unregister() them if you wish to do so.
265 *
266 * @param string Registry key
267 * @param mixed Value to register
268 */
269 public static function Register($key, $value)
270 {
271 if (isset(self::_Instance()->registry["$key"]))
272 {
273 trigger_error('Cannot overwrite a key in the registry');
274 return;
275 }
276
277 self::_Instance()->registry["$key"] = $value;
278 }
279
280 // ###################################################################
281 /**
282 * Unregisters a value from the registry. This removes all traces of
283 * it from this object.
284 *
285 * @param string Registry key
286 */
287 public static function Unregister($key)
288 {
289 if (!isset(self::_Instance()->registry["$key"]))
290 {
291 trigger_error('You cannot unregister a key that does not exist');
292 return;
293 }
294
295 unset(self::_Instance()->registry["$key"]);
296 }
297
298 // ###################################################################
299 /**
300 * This gets a value from the registry with a specific key
301 *
302 * @param string The key
303 *
304 * @return mixed Value in the registry for key
305 */
306 public static function Get($key)
307 {
308 if (!isset(self::_Instance()->registry["$key"]))
309 {
310 trigger_error('Cannot access the registry with a non-existent key');
311 return;
312 }
313
314 return self::_Instance()->registry["$key"];
315 }
316
317 // ###################################################################
318 /**
319 * Returns the first object of a specified class type
320 *
321 * @param string Class name
322 *
323 * @return object Object in the registry of that type
324 */
325 public static function GetType($class)
326 {
327 $class = 'BS' . $class;
328 foreach (self::_Instance()->registry AS $key => $object)
329 {
330 if ($object instanceof $class)
331 {
332 return $object;
333 }
334 }
335 }
336
337 // ###################################################################
338 /**
339 * Returns the entire registry stack
340 *
341 * @return array Complete registry
342 */
343 public static function GetAll()
344 {
345 return self::_Instance()->registry;
346 }
347
348 // ###################################################################
349 /**
350 * Adds a debug message to the array. This only works when debug mode
351 * is enabled.
352 *
353 * @param string Debug message
354 */
355 public static function Debug($msg)
356 {
357 if (self::_Instance()->debug)
358 {
359 self::_Instance()->debugInfo[] = $msg;
360 }
361 }
362
363 // ###################################################################
364 /**
365 * Returns a <select> menu of all the debug notices
366 *
367 * @return string Debug list
368 */
369 public static function GetDebugList()
370 {
371 $output = '<select><option>Debug Notices (' . sizeof(self::_Instance()->debugInfo) . ')</option>';
372 foreach (self::_Instance()->debugInfo AS $notice)
373 {
374 $output .= "<option>--- $notice</option>";
375 }
376 return "$output</select>";
377 }
378
379 // ###################################################################
380 /**
381 * Loads the specified module.
382 *
383 * @param string Module name
384 *
385 * @return object Instantiated module
386 */
387 public static function LoadModule($name)
388 {
389 if (BSRegister::GetDebug())
390 {
391 include_once("ISSO/$name.php");
392 }
393 else
394 {
395 @include_once("ISSO/$name.php");
396 }
397
398 $class = "BS$name";
399
400 if (!class_exists($class))
401 {
402 trigger_error('Specifed module does not conform to the ISSO specification, or the class is missing');
403 return;
404 }
405
406 return new $class;
407 }
408
409 // ###################################################################
410 /**
411 * Prints an ISSO message
412 *
413 * @param string The title of the message
414 * @param string The content of the message
415 * @param integer Type of message to be printed
416 * @param bool Return the output?
417 * @param bool Show the debug stack?
418 * @param integer Message width
419 *
420 * @return mixed Output or null
421 */
422 public static function Message($title, $message, $type, $return = false, $stack = true, $width = 500)
423 {
424 switch ($type)
425 {
426 // Message
427 case 1:
428 $prefix = 'Message';
429 $color = '#669900';
430 $font = '#000000';
431 break;
432
433 // Warning
434 case 2:
435 $prefix = 'Warning';
436 $color = '#003399';
437 $font = '#FFFFFF';
438 break;
439
440 case 3:
441 $prefix = 'Error';
442 $color = '#990000';
443 $font = '#EFEFEF';
444 break;
445 }
446
447 echo "\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;\">";
448 echo "\n<tr style=\"color: $font; text-align: left\">\n\t<td><strong>$prefix: $title</strong></td>\n</tr>";
449 echo "\n<tr style=\"background-color: #FFFFFF; text-align: left\">\n\t<td>$message</td>\n</tr>";
450 if ($stack AND self::_Instance()->getDebug())
451 {
452 echo "\n<tr style=\"background-color: #FFFFFF; text-align: left\">\n\t<td><strong>Debug Stack:</strong> <pre>";
453 echo BSFunctions::FormatBacktrace(debug_backtrace());
454 echo "</pre></td>\n</tr>";
455 }
456 echo "\n</table>\n<br />\n";
457 }
458
459 // ###################################################################
460 /**
461 * Custom error handler for ISSO; only handle E_WARNING, E_NOTICE,
462 * E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE
463 *
464 * @param integer Error number
465 * @param string Error message string
466 * @param string File that contains the error
467 * @param string The line number of the error
468 * @param string The active symbol table at which point the error occurred
469 */
470 public function _errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
471 {
472 $level = ini_get('error_reporting');
473
474 switch ($errno)
475 {
476 // So we don't need to specify the error type in trigger_error(), all E_USER_NOTICEs
477 // are fatal and automatically kill the script
478 case E_USER_NOTICE:
479 $title = 'Fatal';
480 $mode = 3;
481 break;
482
483 // A non-fatal but important warning
484 case E_WARNING:
485 $title = 'Warning';
486 $mode = 2;
487 if (!($level & E_WARNING))
488 {
489 return;
490 }
491 break;
492
493 // A non-fatal notice that should all but be ignored unless in dev environments
494 case E_NOTICE:
495 case E_STRICT:
496 $title = 'Notice';
497 $mode = 1;
498 if (!($level & E_NOTICE))
499 {
500 return;
501 }
502 break;
503
504 case E_USER_WARNING:
505 case E_USER_NOTICE:
506 default:
507 trigger_error('The only error types supported are E_USER_NOTICE (fatal), E_WARNING, and E_NOTICE');
508 break;
509 }
510
511 // change the file and line of the error so we aren't looking at the location of the trigger_error()
512 $backtrace = debug_backtrace();
513 if (isset($backtrace[1]) AND $backtrace[1]['function'] == 'trigger_error' AND isset($backtrace[2]['file']))
514 {
515 $errfile = $backtrace[2]['file'];
516 $errline = $backtrace[2]['line'];
517 }
518
519 $errstr .= " in <strong>$errfile</strong> on line <strong>$errline</strong>";
520
521 $errstr = str_replace(array(getcwd(), dirname(getcwd())), '', $errstr);
522
523 self::Message($title, $errstr, $mode);
524
525 if ($errno == E_USER_NOTICE)
526 {
527 exit;
528 }
529 }
530
531 // ###################################################################
532 /**
533 * Creates a table that explains the error reporting levels and their
534 * state
535 */
536 public static function ExplainErrorReporting()
537 {
538 $levels = array(
539 'E_ERROR' => E_ERROR,
540 'E_WARNING' => E_WARNING,
541 'E_PARSE' => E_PARSE,
542 'E_NOTICE' => E_NOTICE,
543 'E_CORE_ERROR' => E_CORE_ERROR,
544 'E_CORE_WARNING' => E_CORE_WARNING,
545 'E_COMPILE_ERROR' => E_COMPILE_ERROR,
546 'E_COMPILE_WARNING' => E_COMPILE_WARNING,
547 'E_USER_ERROR' => E_USER_ERROR,
548 'E_USER_WARNING' => E_USER_WARNING,
549 'E_USER_NOTICE' => E_USER_NOTICE,
550 'E_ALL' => E_ALL,
551 'E_STRICT' => E_STRICT
552 );
553
554 $table = '<table cellspacing="0" cellpadding="2" border="0">';
555
556 foreach ($levels AS $name => $value)
557 {
558 $table .= '
559 <tr>
560 <td>' . $name . '</td>
561 <td>' . (ini_get('error_reporting') & $value) . '</td>
562 </tr>';
563 }
564
565 $table .= '
566 </table>';
567
568 self::Message('Error Reporting', $table, 1);
569 }
570
571 // ###################################################################
572 /**
573 * This function is used by other framework modules to check and see if
574 * the passed array of module names have been loaded. If not, this will
575 * throw an error informing the developer that the given modules are
576 * required in order for the framework to work.
577 *
578 * @param array Array of module names to check for loadedness
579 */
580 public static function RequiredModules($modules)
581 {
582 foreach ($modules AS $module)
583 {
584 if (self::GetType($module) == null AND !class_exists("BS$module"))
585 {
586 trigger_error('The ' . $module . ' module is required in order to use this framework module');
587 }
588 }
589 }
590 }
591
592 /*=====================================================================*\
593 || ###################################################################
594 || # $HeadURL$
595 || # $Id$
596 || ###################################################################
597 \*=====================================================================*/
598 ?>