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