remove old readme
[atutor.git] / include / classes / XML / XML_HTMLSax / PEAR.php
1 <?php\r
2 /**\r
3  * PEAR, the PHP Extension and Application Repository\r
4  *\r
5  * PEAR class and PEAR_Error class\r
6  *\r
7  * PHP versions 4 and 5\r
8  *\r
9  * LICENSE: This source file is subject to version 3.0 of the PHP license\r
10  * that is available through the world-wide-web at the following URI:\r
11  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of\r
12  * the PHP License and are unable to obtain it through the web, please\r
13  * send a note to license@php.net so we can mail you a copy immediately.\r
14  *\r
15  * @category   pear\r
16  * @package    PEAR\r
17  * @author     Sterling Hughes <sterling@php.net>\r
18  * @author     Stig Bakken <ssb@php.net>\r
19  * @author     Tomas V.V.Cox <cox@idecnet.com>\r
20  * @author     Greg Beaver <cellog@php.net>\r
21  * @copyright  1997-2008 The PHP Group\r
22  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0\r
23  * @version    CVS: $Id$\r
24  * @link       http://pear.php.net/package/PEAR\r
25  * @since      File available since Release 0.1\r
26  */\r
27 \r
28 /**#@+\r
29  * ERROR constants\r
30  */\r
31 define('PEAR_ERROR_RETURN',     1);\r
32 define('PEAR_ERROR_PRINT',      2);\r
33 define('PEAR_ERROR_TRIGGER',    4);\r
34 define('PEAR_ERROR_DIE',        8);\r
35 define('PEAR_ERROR_CALLBACK',  16);\r
36 /**\r
37  * WARNING: obsolete\r
38  * @deprecated\r
39  */\r
40 define('PEAR_ERROR_EXCEPTION', 32);\r
41 /**#@-*/\r
42 define('PEAR_ZE2', (function_exists('version_compare') &&\r
43                     version_compare(zend_version(), "2-dev", "ge")));\r
44 \r
45 if (substr(PHP_OS, 0, 3) == 'WIN') {\r
46     define('OS_WINDOWS', true);\r
47     define('OS_UNIX',    false);\r
48     define('PEAR_OS',    'Windows');\r
49 } else {\r
50     define('OS_WINDOWS', false);\r
51     define('OS_UNIX',    true);\r
52     define('PEAR_OS',    'Unix'); // blatant assumption\r
53 }\r
54 \r
55 // instant backwards compatibility\r
56 if (!defined('PATH_SEPARATOR')) {\r
57     if (OS_WINDOWS) {\r
58         define('PATH_SEPARATOR', ';');\r
59     } else {\r
60         define('PATH_SEPARATOR', ':');\r
61     }\r
62 }\r
63 \r
64 $GLOBALS['_PEAR_default_error_mode']     = PEAR_ERROR_RETURN;\r
65 $GLOBALS['_PEAR_default_error_options']  = E_USER_NOTICE;\r
66 $GLOBALS['_PEAR_destructor_object_list'] = array();\r
67 $GLOBALS['_PEAR_shutdown_funcs']         = array();\r
68 $GLOBALS['_PEAR_error_handler_stack']    = array();\r
69 \r
70 @ini_set('track_errors', true);\r
71 \r
72 /**\r
73  * Base class for other PEAR classes.  Provides rudimentary\r
74  * emulation of destructors.\r
75  *\r
76  * If you want a destructor in your class, inherit PEAR and make a\r
77  * destructor method called _yourclassname (same name as the\r
78  * constructor, but with a "_" prefix).  Also, in your constructor you\r
79  * have to call the PEAR constructor: $this->PEAR();.\r
80  * The destructor method will be called without parameters.  Note that\r
81  * at in some SAPI implementations (such as Apache), any output during\r
82  * the request shutdown (in which destructors are called) seems to be\r
83  * discarded.  If you need to get any debug information from your\r
84  * destructor, use error_log(), syslog() or something similar.\r
85  *\r
86  * IMPORTANT! To use the emulated destructors you need to create the\r
87  * objects by reference: $obj = new PEAR_child;\r
88  *\r
89  * @category   pear\r
90  * @package    PEAR\r
91  * @author     Stig Bakken <ssb@php.net>\r
92  * @author     Tomas V.V. Cox <cox@idecnet.com>\r
93  * @author     Greg Beaver <cellog@php.net>\r
94  * @copyright  1997-2008 The PHP Group\r
95  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0\r
96  * @version    Release: 1.4.4\r
97  * @link       http://pear.php.net/package/PEAR\r
98  * @see        PEAR_Error\r
99  * @since      Class available since PHP 4.0.2\r
100  * @link        http://pear.php.net/manual/en/core.pear.php#core.pear.pear\r
101  */\r
102 class PEAR\r
103 {\r
104     // {{{ properties\r
105 \r
106     /**\r
107      * Whether to enable internal debug messages.\r
108      *\r
109      * @var     bool\r
110      * @access  private\r
111      */\r
112     var $_debug = false;\r
113 \r
114     /**\r
115      * Default error mode for this object.\r
116      *\r
117      * @var     int\r
118      * @access  private\r
119      */\r
120     var $_default_error_mode = null;\r
121 \r
122     /**\r
123      * Default error options used for this object when error mode\r
124      * is PEAR_ERROR_TRIGGER.\r
125      *\r
126      * @var     int\r
127      * @access  private\r
128      */\r
129     var $_default_error_options = null;\r
130 \r
131     /**\r
132      * Default error handler (callback) for this object, if error mode is\r
133      * PEAR_ERROR_CALLBACK.\r
134      *\r
135      * @var     string\r
136      * @access  private\r
137      */\r
138     var $_default_error_handler = '';\r
139 \r
140     /**\r
141      * Which class to use for error objects.\r
142      *\r
143      * @var     string\r
144      * @access  private\r
145      */\r
146     var $_error_class = 'PEAR_Error';\r
147 \r
148     /**\r
149      * An array of expected errors.\r
150      *\r
151      * @var     array\r
152      * @access  private\r
153      */\r
154     var $_expected_errors = array();\r
155 \r
156     // }}}\r
157 \r
158     // {{{ constructor\r
159 \r
160     /**\r
161      * Constructor.  Registers this object in\r
162      * $_PEAR_destructor_object_list for destructor emulation if a\r
163      * destructor object exists.\r
164      *\r
165      * @param string $error_class  (optional) which class to use for\r
166      *        error objects, defaults to PEAR_Error.\r
167      * @access public\r
168      * @return void\r
169      */\r
170     function PEAR($error_class = null)\r
171     {\r
172         $classname = strtolower(get_class($this));\r
173         if ($this->_debug) {\r
174             print "PEAR constructor called, class=$classname\n";\r
175         }\r
176         if ($error_class !== null) {\r
177             $this->_error_class = $error_class;\r
178         }\r
179         while ($classname && strcasecmp($classname, "pear")) {\r
180             $destructor = "_$classname";\r
181             if (method_exists($this, $destructor)) {\r
182                 global $_PEAR_destructor_object_list;\r
183                 $_PEAR_destructor_object_list[] = &$this;\r
184                 if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {\r
185                     register_shutdown_function("_PEAR_call_destructors");\r
186                     $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;\r
187                 }\r
188                 break;\r
189             } else {\r
190                 $classname = get_parent_class($classname);\r
191             }\r
192         }\r
193     }\r
194 \r
195     // }}}\r
196     // {{{ destructor\r
197 \r
198     /**\r
199      * Destructor (the emulated type of...).  Does nothing right now,\r
200      * but is included for forward compatibility, so subclass\r
201      * destructors should always call it.\r
202      *\r
203      * See the note in the class desciption about output from\r
204      * destructors.\r
205      *\r
206      * @access public\r
207      * @return void\r
208      */\r
209     function _PEAR() {\r
210         if ($this->_debug) {\r
211             printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));\r
212         }\r
213     }\r
214 \r
215     // }}}\r
216     // {{{ getStaticProperty()\r
217 \r
218     /**\r
219     * If you have a class that's mostly/entirely static, and you need static\r
220     * properties, you can use this method to simulate them. Eg. in your method(s)\r
221     * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');\r
222     * You MUST use a reference, or they will not persist!\r
223     *\r
224     * @access public\r
225     * @param  string $class  The calling classname, to prevent clashes\r
226     * @param  string $var    The variable to retrieve.\r
227     * @return mixed   A reference to the variable. If not set it will be\r
228     *                 auto initialised to NULL.\r
229     */\r
230     function &getStaticProperty($class, $var)\r
231     {\r
232         static $properties;\r
233         return $properties[$class][$var];\r
234     }\r
235 \r
236     // }}}\r
237     // {{{ registerShutdownFunc()\r
238 \r
239     /**\r
240     * Use this function to register a shutdown method for static\r
241     * classes.\r
242     *\r
243     * @access public\r
244     * @param  mixed $func  The function name (or array of class/method) to call\r
245     * @param  mixed $args  The arguments to pass to the function\r
246     * @return void\r
247     */\r
248     function registerShutdownFunc($func, $args = array())\r
249     {\r
250         $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);\r
251     }\r
252 \r
253     // }}}\r
254     // {{{ isError()\r
255 \r
256     /**\r
257      * Tell whether a value is a PEAR error.\r
258      *\r
259      * @param   mixed $data   the value to test\r
260      * @param   int   $code   if $data is an error object, return true\r
261      *                        only if $code is a string and\r
262      *                        $obj->getMessage() == $code or\r
263      *                        $code is an integer and $obj->getCode() == $code\r
264      * @access  public\r
265      * @return  bool    true if parameter is an error\r
266      */\r
267     function isError($data, $code = null)\r
268     {\r
269         if (is_a($data, 'PEAR_Error')) {\r
270             if (is_null($code)) {\r
271                 return true;\r
272             } elseif (is_string($code)) {\r
273                 return $data->getMessage() == $code;\r
274             } else {\r
275                 return $data->getCode() == $code;\r
276             }\r
277         }\r
278         return false;\r
279     }\r
280 \r
281     // }}}\r
282     // {{{ setErrorHandling()\r
283 \r
284     /**\r
285      * Sets how errors generated by this object should be handled.\r
286      * Can be invoked both in objects and statically.  If called\r
287      * statically, setErrorHandling sets the default behaviour for all\r
288      * PEAR objects.  If called in an object, setErrorHandling sets\r
289      * the default behaviour for that object.\r
290      *\r
291      * @param int $mode\r
292      *        One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,\r
293      *        PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,\r
294      *        PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.\r
295      *\r
296      * @param mixed $options\r
297      *        When $mode is PEAR_ERROR_TRIGGER, this is the error level (one\r
298      *        of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).\r
299      *\r
300      *        When $mode is PEAR_ERROR_CALLBACK, this parameter is expected\r
301      *        to be the callback function or method.  A callback\r
302      *        function is a string with the name of the function, a\r
303      *        callback method is an array of two elements: the element\r
304      *        at index 0 is the object, and the element at index 1 is\r
305      *        the name of the method to call in the object.\r
306      *\r
307      *        When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is\r
308      *        a printf format string used when printing the error\r
309      *        message.\r
310      *\r
311      * @access public\r
312      * @return void\r
313      * @see PEAR_ERROR_RETURN\r
314      * @see PEAR_ERROR_PRINT\r
315      * @see PEAR_ERROR_TRIGGER\r
316      * @see PEAR_ERROR_DIE\r
317      * @see PEAR_ERROR_CALLBACK\r
318      * @see PEAR_ERROR_EXCEPTION\r
319      *\r
320      * @since PHP 4.0.5\r
321      */\r
322 \r
323     function setErrorHandling($mode = null, $options = null)\r
324     {\r
325         if (isset($this) && is_a($this, 'PEAR')) {\r
326             $setmode     = &$this->_default_error_mode;\r
327             $setoptions  = &$this->_default_error_options;\r
328         } else {\r
329             $setmode     = &$GLOBALS['_PEAR_default_error_mode'];\r
330             $setoptions  = &$GLOBALS['_PEAR_default_error_options'];\r
331         }\r
332 \r
333         switch ($mode) {\r
334             case PEAR_ERROR_EXCEPTION:\r
335             case PEAR_ERROR_RETURN:\r
336             case PEAR_ERROR_PRINT:\r
337             case PEAR_ERROR_TRIGGER:\r
338             case PEAR_ERROR_DIE:\r
339             case null:\r
340                 $setmode = $mode;\r
341                 $setoptions = $options;\r
342                 break;\r
343 \r
344             case PEAR_ERROR_CALLBACK:\r
345                 $setmode = $mode;\r
346                 // class/object method callback\r
347                 if (is_callable($options)) {\r
348                     $setoptions = $options;\r
349                 } else {\r
350                     trigger_error("invalid error callback", E_USER_WARNING);\r
351                 }\r
352                 break;\r
353 \r
354             default:\r
355                 trigger_error("invalid error mode", E_USER_WARNING);\r
356                 break;\r
357         }\r
358     }\r
359 \r
360     // }}}\r
361     // {{{ expectError()\r
362 \r
363     /**\r
364      * This method is used to tell which errors you expect to get.\r
365      * Expected errors are always returned with error mode\r
366      * PEAR_ERROR_RETURN.  Expected error codes are stored in a stack,\r
367      * and this method pushes a new element onto it.  The list of\r
368      * expected errors are in effect until they are popped off the\r
369      * stack with the popExpect() method.\r
370      *\r
371      * Note that this method can not be called statically\r
372      *\r
373      * @param mixed $code a single error code or an array of error codes to expect\r
374      *\r
375      * @return int     the new depth of the "expected errors" stack\r
376      * @access public\r
377      */\r
378     function expectError($code = '*')\r
379     {\r
380         if (is_array($code)) {\r
381             array_push($this->_expected_errors, $code);\r
382         } else {\r
383             array_push($this->_expected_errors, array($code));\r
384         }\r
385         return sizeof($this->_expected_errors);\r
386     }\r
387 \r
388     // }}}\r
389     // {{{ popExpect()\r
390 \r
391     /**\r
392      * This method pops one element off the expected error codes\r
393      * stack.\r
394      *\r
395      * @return array   the list of error codes that were popped\r
396      */\r
397     function popExpect()\r
398     {\r
399         return array_pop($this->_expected_errors);\r
400     }\r
401 \r
402     // }}}\r
403     // {{{ _checkDelExpect()\r
404 \r
405     /**\r
406      * This method checks unsets an error code if available\r
407      *\r
408      * @param mixed error code\r
409      * @return bool true if the error code was unset, false otherwise\r
410      * @access private\r
411      * @since PHP 4.3.0\r
412      */\r
413     function _checkDelExpect($error_code)\r
414     {\r
415         $deleted = false;\r
416 \r
417         foreach ($this->_expected_errors AS $key => $error_array) {\r
418             if (in_array($error_code, $error_array)) {\r
419                 unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);\r
420                 $deleted = true;\r
421             }\r
422 \r
423             // clean up empty arrays\r
424             if (0 == count($this->_expected_errors[$key])) {\r
425                 unset($this->_expected_errors[$key]);\r
426             }\r
427         }\r
428         return $deleted;\r
429     }\r
430 \r
431     // }}}\r
432     // {{{ delExpect()\r
433 \r
434     /**\r
435      * This method deletes all occurences of the specified element from\r
436      * the expected error codes stack.\r
437      *\r
438      * @param  mixed $error_code error code that should be deleted\r
439      * @return mixed list of error codes that were deleted or error\r
440      * @access public\r
441      * @since PHP 4.3.0\r
442      */\r
443     function delExpect($error_code)\r
444     {\r
445         $deleted = false;\r
446 \r
447         if ((is_array($error_code) && (0 != count($error_code)))) {\r
448             // $error_code is a non-empty array here;\r
449             // we walk through it trying to unset all\r
450             // values\r
451             foreach($error_code as $key => $error) {\r
452                 if ($this->_checkDelExpect($error)) {\r
453                     $deleted =  true;\r
454                 } else {\r
455                     $deleted = false;\r
456                 }\r
457             }\r
458             return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME\r
459         } elseif (!empty($error_code)) {\r
460             // $error_code comes alone, trying to unset it\r
461             if ($this->_checkDelExpect($error_code)) {\r
462                 return true;\r
463             } else {\r
464                 return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME\r
465             }\r
466         } else {\r
467             // $error_code is empty\r
468             return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME\r
469         }\r
470     }\r
471 \r
472     // }}}\r
473     // {{{ raiseError()\r
474 \r
475     /**\r
476      * This method is a wrapper that returns an instance of the\r
477      * configured error class with this object's default error\r
478      * handling applied.  If the $mode and $options parameters are not\r
479      * specified, the object's defaults are used.\r
480      *\r
481      * @param mixed $message a text error message or a PEAR error object\r
482      *\r
483      * @param int $code      a numeric error code (it is up to your class\r
484      *                  to define these if you want to use codes)\r
485      *\r
486      * @param int $mode      One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,\r
487      *                  PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,\r
488      *                  PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.\r
489      *\r
490      * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter\r
491      *                  specifies the PHP-internal error level (one of\r
492      *                  E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).\r
493      *                  If $mode is PEAR_ERROR_CALLBACK, this\r
494      *                  parameter specifies the callback function or\r
495      *                  method.  In other error modes this parameter\r
496      *                  is ignored.\r
497      *\r
498      * @param string $userinfo If you need to pass along for example debug\r
499      *                  information, this parameter is meant for that.\r
500      *\r
501      * @param string $error_class The returned error object will be\r
502      *                  instantiated from this class, if specified.\r
503      *\r
504      * @param bool $skipmsg If true, raiseError will only pass error codes,\r
505      *                  the error message parameter will be dropped.\r
506      *\r
507      * @access public\r
508      * @return object   a PEAR error object\r
509      * @see PEAR::setErrorHandling\r
510      * @since PHP 4.0.5\r
511      */\r
512     function &raiseError($message = null,\r
513                          $code = null,\r
514                          $mode = null,\r
515                          $options = null,\r
516                          $userinfo = null,\r
517                          $error_class = null,\r
518                          $skipmsg = false)\r
519     {\r
520         // The error is yet a PEAR error object\r
521         if (is_object($message)) {\r
522             $code        = $message->getCode();\r
523             $userinfo    = $message->getUserInfo();\r
524             $error_class = $message->getType();\r
525             $message->error_message_prefix = '';\r
526             $message     = $message->getMessage();\r
527         }\r
528 \r
529         if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {\r
530             if ($exp[0] == "*" ||\r
531                 (is_int(reset($exp)) && in_array($code, $exp)) ||\r
532                 (is_string(reset($exp)) && in_array($message, $exp))) {\r
533                 $mode = PEAR_ERROR_RETURN;\r
534             }\r
535         }\r
536         // No mode given, try global ones\r
537         if ($mode === null) {\r
538             // Class error handler\r
539             if (isset($this) && isset($this->_default_error_mode)) {\r
540                 $mode    = $this->_default_error_mode;\r
541                 $options = $this->_default_error_options;\r
542             // Global error handler\r
543             } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {\r
544                 $mode    = $GLOBALS['_PEAR_default_error_mode'];\r
545                 $options = $GLOBALS['_PEAR_default_error_options'];\r
546             }\r
547         }\r
548 \r
549         if ($error_class !== null) {\r
550             $ec = $error_class;\r
551         } elseif (isset($this) && isset($this->_error_class)) {\r
552             $ec = $this->_error_class;\r
553         } else {\r
554             $ec = 'PEAR_Error';\r
555         }\r
556         if ($skipmsg) {\r
557             $a = new $ec($code, $mode, $options, $userinfo);\r
558             return $a;\r
559         } else {\r
560             $a = new $ec($message, $code, $mode, $options, $userinfo);\r
561             return $a;\r
562         }\r
563     }\r
564 \r
565     // }}}\r
566     // {{{ throwError()\r
567 \r
568     /**\r
569      * Simpler form of raiseError with fewer options.  In most cases\r
570      * message, code and userinfo are enough.\r
571      *\r
572      * @param string $message\r
573      *\r
574      */\r
575     function &throwError($message = null,\r
576                          $code = null,\r
577                          $userinfo = null)\r
578     {\r
579         if (isset($this) && is_a($this, 'PEAR')) {\r
580             $a = &$this->raiseError($message, $code, null, null, $userinfo);\r
581             return $a;\r
582         } else {\r
583             $a = &PEAR::raiseError($message, $code, null, null, $userinfo);\r
584             return $a;\r
585         }\r
586     }\r
587 \r
588     // }}}\r
589     function staticPushErrorHandling($mode, $options = null)\r
590     {\r
591         $stack = &$GLOBALS['_PEAR_error_handler_stack'];\r
592         $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];\r
593         $def_options = &$GLOBALS['_PEAR_default_error_options'];\r
594         $stack[] = array($def_mode, $def_options);\r
595         switch ($mode) {\r
596             case PEAR_ERROR_EXCEPTION:\r
597             case PEAR_ERROR_RETURN:\r
598             case PEAR_ERROR_PRINT:\r
599             case PEAR_ERROR_TRIGGER:\r
600             case PEAR_ERROR_DIE:\r
601             case null:\r
602                 $def_mode = $mode;\r
603                 $def_options = $options;\r
604                 break;\r
605 \r
606             case PEAR_ERROR_CALLBACK:\r
607                 $def_mode = $mode;\r
608                 // class/object method callback\r
609                 if (is_callable($options)) {\r
610                     $def_options = $options;\r
611                 } else {\r
612                     trigger_error("invalid error callback", E_USER_WARNING);\r
613                 }\r
614                 break;\r
615 \r
616             default:\r
617                 trigger_error("invalid error mode", E_USER_WARNING);\r
618                 break;\r
619         }\r
620         $stack[] = array($mode, $options);\r
621         return true;\r
622     }\r
623 \r
624     function staticPopErrorHandling()\r
625     {\r
626         $stack = &$GLOBALS['_PEAR_error_handler_stack'];\r
627         $setmode     = &$GLOBALS['_PEAR_default_error_mode'];\r
628         $setoptions  = &$GLOBALS['_PEAR_default_error_options'];\r
629         array_pop($stack);\r
630         list($mode, $options) = $stack[sizeof($stack) - 1];\r
631         array_pop($stack);\r
632         switch ($mode) {\r
633             case PEAR_ERROR_EXCEPTION:\r
634             case PEAR_ERROR_RETURN:\r
635             case PEAR_ERROR_PRINT:\r
636             case PEAR_ERROR_TRIGGER:\r
637             case PEAR_ERROR_DIE:\r
638             case null:\r
639                 $setmode = $mode;\r
640                 $setoptions = $options;\r
641                 break;\r
642 \r
643             case PEAR_ERROR_CALLBACK:\r
644                 $setmode = $mode;\r
645                 // class/object method callback\r
646                 if (is_callable($options)) {\r
647                     $setoptions = $options;\r
648                 } else {\r
649                     trigger_error("invalid error callback", E_USER_WARNING);\r
650                 }\r
651                 break;\r
652 \r
653             default:\r
654                 trigger_error("invalid error mode", E_USER_WARNING);\r
655                 break;\r
656         }\r
657         return true;\r
658     }\r
659 \r
660     // {{{ pushErrorHandling()\r
661 \r
662     /**\r
663      * Push a new error handler on top of the error handler options stack. With this\r
664      * you can easily override the actual error handler for some code and restore\r
665      * it later with popErrorHandling.\r
666      *\r
667      * @param mixed $mode (same as setErrorHandling)\r
668      * @param mixed $options (same as setErrorHandling)\r
669      *\r
670      * @return bool Always true\r
671      *\r
672      * @see PEAR::setErrorHandling\r
673      */\r
674     function pushErrorHandling($mode, $options = null)\r
675     {\r
676         $stack = &$GLOBALS['_PEAR_error_handler_stack'];\r
677         if (isset($this) && is_a($this, 'PEAR')) {\r
678             $def_mode    = &$this->_default_error_mode;\r
679             $def_options = &$this->_default_error_options;\r
680         } else {\r
681             $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];\r
682             $def_options = &$GLOBALS['_PEAR_default_error_options'];\r
683         }\r
684         $stack[] = array($def_mode, $def_options);\r
685 \r
686         if (isset($this) && is_a($this, 'PEAR')) {\r
687             $this->setErrorHandling($mode, $options);\r
688         } else {\r
689             PEAR::setErrorHandling($mode, $options);\r
690         }\r
691         $stack[] = array($mode, $options);\r
692         return true;\r
693     }\r
694 \r
695     // }}}\r
696     // {{{ popErrorHandling()\r
697 \r
698     /**\r
699     * Pop the last error handler used\r
700     *\r
701     * @return bool Always true\r
702     *\r
703     * @see PEAR::pushErrorHandling\r
704     */\r
705     function popErrorHandling()\r
706     {\r
707         $stack = &$GLOBALS['_PEAR_error_handler_stack'];\r
708         array_pop($stack);\r
709         list($mode, $options) = $stack[sizeof($stack) - 1];\r
710         array_pop($stack);\r
711         if (isset($this) && is_a($this, 'PEAR')) {\r
712             $this->setErrorHandling($mode, $options);\r
713         } else {\r
714             PEAR::setErrorHandling($mode, $options);\r
715         }\r
716         return true;\r
717     }\r
718 \r
719     // }}}\r
720     // {{{ loadExtension()\r
721 \r
722     /**\r
723     * OS independant PHP extension load. Remember to take care\r
724     * on the correct extension name for case sensitive OSes.\r
725     *\r
726     * @param string $ext The extension name\r
727     * @return bool Success or not on the dl() call\r
728     */\r
729     function loadExtension($ext)\r
730     {\r
731         if (!extension_loaded($ext)) {\r
732             // if either returns true dl() will produce a FATAL error, stop that\r
733             if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {\r
734                 return false;\r
735             }\r
736             if (OS_WINDOWS) {\r
737                 $suffix = '.dll';\r
738             } elseif (PHP_OS == 'HP-UX') {\r
739                 $suffix = '.sl';\r
740             } elseif (PHP_OS == 'AIX') {\r
741                 $suffix = '.a';\r
742             } elseif (PHP_OS == 'OSX') {\r
743                 $suffix = '.bundle';\r
744             } else {\r
745                 $suffix = '.so';\r
746             }\r
747             return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);\r
748         }\r
749         return true;\r
750     }\r
751 \r
752     // }}}\r
753 }\r
754 \r
755 // {{{ _PEAR_call_destructors()\r
756 \r
757 function _PEAR_call_destructors()\r
758 {\r
759     global $_PEAR_destructor_object_list;\r
760     if (is_array($_PEAR_destructor_object_list) &&\r
761         sizeof($_PEAR_destructor_object_list))\r
762     {\r
763         reset($_PEAR_destructor_object_list);\r
764         if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) {\r
765             $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);\r
766         }\r
767         while (list($k, $objref) = each($_PEAR_destructor_object_list)) {\r
768             $classname = get_class($objref);\r
769             while ($classname) {\r
770                 $destructor = "_$classname";\r
771                 if (method_exists($objref, $destructor)) {\r
772                     $objref->$destructor();\r
773                     break;\r
774                 } else {\r
775                     $classname = get_parent_class($classname);\r
776                 }\r
777             }\r
778         }\r
779         // Empty the object list to ensure that destructors are\r
780         // not called more than once.\r
781         $_PEAR_destructor_object_list = array();\r
782     }\r
783 \r
784     // Now call the shutdown functions\r
785     if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {\r
786         foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {\r
787             call_user_func_array($value[0], $value[1]);\r
788         }\r
789     }\r
790 }\r
791 \r
792 // }}}\r
793 /**\r
794  * Standard PEAR error class for PHP 4\r
795  *\r
796  * This class is supserseded by {@link PEAR_Exception} in PHP 5\r
797  *\r
798  * @category   pear\r
799  * @package    PEAR\r
800  * @author     Stig Bakken <ssb@php.net>\r
801  * @author     Tomas V.V. Cox <cox@idecnet.com>\r
802  * @author     Gregory Beaver <cellog@php.net>\r
803  * @copyright  1997-2008 The PHP Group\r
804  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0\r
805  * @version    Release: 1.4.4\r
806  * @link       http://pear.php.net/manual/en/core.pear.pear-error.php\r
807  * @see        PEAR::raiseError(), PEAR::throwError()\r
808  * @since      Class available since PHP 4.0.2\r
809  */\r
810 class PEAR_Error\r
811 {\r
812     // {{{ properties\r
813 \r
814     var $error_message_prefix = '';\r
815     var $mode                 = PEAR_ERROR_RETURN;\r
816     var $level                = E_USER_NOTICE;\r
817     var $code                 = -1;\r
818     var $message              = '';\r
819     var $userinfo             = '';\r
820     var $backtrace            = null;\r
821 \r
822     // }}}\r
823     // {{{ constructor\r
824 \r
825     /**\r
826      * PEAR_Error constructor\r
827      *\r
828      * @param string $message  message\r
829      *\r
830      * @param int $code     (optional) error code\r
831      *\r
832      * @param int $mode     (optional) error mode, one of: PEAR_ERROR_RETURN,\r
833      * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,\r
834      * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION\r
835      *\r
836      * @param mixed $options   (optional) error level, _OR_ in the case of\r
837      * PEAR_ERROR_CALLBACK, the callback function or object/method\r
838      * tuple.\r
839      *\r
840      * @param string $userinfo (optional) additional user/debug info\r
841      *\r
842      * @access public\r
843      *\r
844      */\r
845     function PEAR_Error($message = 'unknown error', $code = null,\r
846                         $mode = null, $options = null, $userinfo = null)\r
847     {\r
848         if ($mode === null) {\r
849             $mode = PEAR_ERROR_RETURN;\r
850         }\r
851         $this->message   = $message;\r
852         $this->code      = $code;\r
853         $this->mode      = $mode;\r
854         $this->userinfo  = $userinfo;\r
855         if (function_exists("debug_backtrace")) {\r
856             if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {\r
857                 $this->backtrace = debug_backtrace();\r
858             }\r
859         }\r
860         if ($mode & PEAR_ERROR_CALLBACK) {\r
861             $this->level = E_USER_NOTICE;\r
862             $this->callback = $options;\r
863         } else {\r
864             if ($options === null) {\r
865                 $options = E_USER_NOTICE;\r
866             }\r
867             $this->level = $options;\r
868             $this->callback = null;\r
869         }\r
870         if ($this->mode & PEAR_ERROR_PRINT) {\r
871             if (is_null($options) || is_int($options)) {\r
872                 $format = "%s";\r
873             } else {\r
874                 $format = $options;\r
875             }\r
876             printf($format, $this->getMessage());\r
877         }\r
878         if ($this->mode & PEAR_ERROR_TRIGGER) {\r
879             trigger_error($this->getMessage(), $this->level);\r
880         }\r
881         if ($this->mode & PEAR_ERROR_DIE) {\r
882             $msg = $this->getMessage();\r
883             if (is_null($options) || is_int($options)) {\r
884                 $format = "%s";\r
885                 if (substr($msg, -1) != "\n") {\r
886                     $msg .= "\n";\r
887                 }\r
888             } else {\r
889                 $format = $options;\r
890             }\r
891             die(sprintf($format, $msg));\r
892         }\r
893         if ($this->mode & PEAR_ERROR_CALLBACK) {\r
894             if (is_callable($this->callback)) {\r
895                 call_user_func($this->callback, $this);\r
896             }\r
897         }\r
898         if ($this->mode & PEAR_ERROR_EXCEPTION) {\r
899             trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);\r
900             eval('$e = new Exception($this->message, $this->code);throw($e);');\r
901         }\r
902     }\r
903 \r
904     // }}}\r
905     // {{{ getMode()\r
906 \r
907     /**\r
908      * Get the error mode from an error object.\r
909      *\r
910      * @return int error mode\r
911      * @access public\r
912      */\r
913     function getMode() {\r
914         return $this->mode;\r
915     }\r
916 \r
917     // }}}\r
918     // {{{ getCallback()\r
919 \r
920     /**\r
921      * Get the callback function/method from an error object.\r
922      *\r
923      * @return mixed callback function or object/method array\r
924      * @access public\r
925      */\r
926     function getCallback() {\r
927         return $this->callback;\r
928     }\r
929 \r
930     // }}}\r
931     // {{{ getMessage()\r
932 \r
933 \r
934     /**\r
935      * Get the error message from an error object.\r
936      *\r
937      * @return  string  full error message\r
938      * @access public\r
939      */\r
940     function getMessage()\r
941     {\r
942         return ($this->error_message_prefix . $this->message);\r
943     }\r
944 \r
945 \r
946     // }}}\r
947     // {{{ getCode()\r
948 \r
949     /**\r
950      * Get error code from an error object\r
951      *\r
952      * @return int error code\r
953      * @access public\r
954      */\r
955      function getCode()\r
956      {\r
957         return $this->code;\r
958      }\r
959 \r
960     // }}}\r
961     // {{{ getType()\r
962 \r
963     /**\r
964      * Get the name of this error/exception.\r
965      *\r
966      * @return string error/exception name (type)\r
967      * @access public\r
968      */\r
969     function getType()\r
970     {\r
971         return get_class($this);\r
972     }\r
973 \r
974     // }}}\r
975     // {{{ getUserInfo()\r
976 \r
977     /**\r
978      * Get additional user-supplied information.\r
979      *\r
980      * @return string user-supplied information\r
981      * @access public\r
982      */\r
983     function getUserInfo()\r
984     {\r
985         return $this->userinfo;\r
986     }\r
987 \r
988     // }}}\r
989     // {{{ getDebugInfo()\r
990 \r
991     /**\r
992      * Get additional debug information supplied by the application.\r
993      *\r
994      * @return string debug information\r
995      * @access public\r
996      */\r
997     function getDebugInfo()\r
998     {\r
999         return $this->getUserInfo();\r
1000     }\r
1001 \r
1002     // }}}\r
1003     // {{{ getBacktrace()\r
1004 \r
1005     /**\r
1006      * Get the call backtrace from where the error was generated.\r
1007      * Supported with PHP 4.3.0 or newer.\r
1008      *\r
1009      * @param int $frame (optional) what frame to fetch\r
1010      * @return array Backtrace, or NULL if not available.\r
1011      * @access public\r
1012      */\r
1013     function getBacktrace($frame = null)\r
1014     {\r
1015         if (defined('PEAR_IGNORE_BACKTRACE')) {\r
1016             return null;\r
1017         }\r
1018         if ($frame === null) {\r
1019             return $this->backtrace;\r
1020         }\r
1021         return $this->backtrace[$frame];\r
1022     }\r
1023 \r
1024     // }}}\r
1025     // {{{ addUserInfo()\r
1026 \r
1027     function addUserInfo($info)\r
1028     {\r
1029         if (empty($this->userinfo)) {\r
1030             $this->userinfo = $info;\r
1031         } else {\r
1032             $this->userinfo .= " ** $info";\r
1033         }\r
1034     }\r
1035 \r
1036     // }}}\r
1037     // {{{ toString()\r
1038 \r
1039     /**\r
1040      * Make a string representation of this object.\r
1041      *\r
1042      * @return string a string with an object summary\r
1043      * @access public\r
1044      */\r
1045     function toString() {\r
1046         $modes = array();\r
1047         $levels = array(E_USER_NOTICE  => 'notice',\r
1048                         E_USER_WARNING => 'warning',\r
1049                         E_USER_ERROR   => 'error');\r
1050         if ($this->mode & PEAR_ERROR_CALLBACK) {\r
1051             if (is_array($this->callback)) {\r
1052                 $callback = (is_object($this->callback[0]) ?\r
1053                     strtolower(get_class($this->callback[0])) :\r
1054                     $this->callback[0]) . '::' .\r
1055                     $this->callback[1];\r
1056             } else {\r
1057                 $callback = $this->callback;\r
1058             }\r
1059             return sprintf('[%s: message="%s" code=%d mode=callback '.\r
1060                            'callback=%s prefix="%s" info="%s"]',\r
1061                            strtolower(get_class($this)), $this->message, $this->code,\r
1062                            $callback, $this->error_message_prefix,\r
1063                            $this->userinfo);\r
1064         }\r
1065         if ($this->mode & PEAR_ERROR_PRINT) {\r
1066             $modes[] = 'print';\r
1067         }\r
1068         if ($this->mode & PEAR_ERROR_TRIGGER) {\r
1069             $modes[] = 'trigger';\r
1070         }\r
1071         if ($this->mode & PEAR_ERROR_DIE) {\r
1072             $modes[] = 'die';\r
1073         }\r
1074         if ($this->mode & PEAR_ERROR_RETURN) {\r
1075             $modes[] = 'return';\r
1076         }\r
1077         return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.\r
1078                        'prefix="%s" info="%s"]',\r
1079                        strtolower(get_class($this)), $this->message, $this->code,\r
1080                        implode("|", $modes), $levels[$this->level],\r
1081                        $this->error_message_prefix,\r
1082                        $this->userinfo);\r
1083     }\r
1084 \r
1085     // }}}\r
1086 }\r
1087 \r
1088 /*\r
1089  * Local Variables:\r
1090  * mode: php\r
1091  * tab-width: 4\r
1092  * c-basic-offset: 4\r
1093  * End:\r
1094  */\r
1095 ?>\r