You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

969 lines
29KB

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