43 $GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'] = array();
57 $GLOBALS[
'_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
70 $GLOBALS[
'_PEAR_ERRORSTACK_DEFAULT_LOGGER'] =
false;
81 $GLOBALS[
'_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
91 define(
'PEAR_ERRORSTACK_PUSHANDLOG', 1);
96 define(
'PEAR_ERRORSTACK_PUSH', 2);
101 define(
'PEAR_ERRORSTACK_LOG', 3);
105 define(
'PEAR_ERRORSTACK_IGNORE', 4);
109 define(
'PEAR_ERRORSTACK_DIE', 5);
116 define(
'PEAR_ERRORSTACK_ERR_NONCLASS', 1);
122 define(
'PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
231 function __construct($package, $msgCallback =
false, $contextCallback =
false,
232 $throwPEAR_Error =
false)
234 $this->_package = $package;
237 $this->_compat = $throwPEAR_Error;
255 $package, $msgCallback =
false, $contextCallback =
false,
256 $throwPEAR_Error =
false, $stackClass =
'PEAR_ErrorStack'
258 if (isset(
$GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'][$package])) {
259 return $GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'][$package];
261 if (!class_exists($stackClass)) {
262 if (function_exists(
'debug_backtrace')) {
263 $trace = debug_backtrace();
266 'exception', array(
'stackclass' => $stackClass),
267 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
270 $GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'][$package] =
271 new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
273 return $GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'][$package];
284 if ($err[
'level'] ==
'exception') {
285 $message = $err[
'message'];
286 if (isset($_SERVER[
'REQUEST_URI'])) {
291 var_dump($err[
'context']);
302 if (is_object($log) && method_exists($log,
'log') ) {
303 $GLOBALS[
'_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
304 } elseif (is_callable($log)) {
305 $GLOBALS[
'_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
315 if (is_object($log) && method_exists($log,
'log') ) {
316 $this->_logger = &$log;
317 } elseif (is_callable($log)) {
318 $this->_logger = &$log;
332 $this->_msgCallback = array(&$this,
'getErrorMessage');
334 if (is_callable($msgCallback)) {
335 $this->_msgCallback = $msgCallback;
362 if (!is_callable($callback)) {
365 $package = $package ? $package :
'*';
366 $GLOBALS[
'_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;
379 if ($contextCallback ===
null) {
380 return $this->_contextCallback =
false;
382 if (!$contextCallback) {
383 $this->_contextCallback = array(&$this,
'getFileLine');
385 if (is_callable($contextCallback)) {
386 $this->_contextCallback = $contextCallback;
408 array_push($this->_errorCallback, $cb);
418 if (!
count($this->_errorCallback)) {
421 return array_pop($this->_errorCallback);
435 array_push(
$GLOBALS[
'_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
445 $ret = array_pop(
$GLOBALS[
'_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
446 if (!is_array(
$GLOBALS[
'_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
447 $GLOBALS[
'_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
493 function push($code, $level =
'error', $params = array(), $msg =
false,
494 $repackage =
false, $backtrace =
false)
498 if ($this->_contextCallback) {
500 $backtrace = debug_backtrace();
502 $context = call_user_func($this->_contextCallback, $code, $params, $backtrace);
506 $time = explode(
' ', microtime());
507 $time = $time[1] + $time[0];
511 'package' => $this->_package,
514 'context' => $context,
519 $err[
'repackage'] = $repackage;
523 if ($this->_msgCallback) {
524 $msg = call_user_func_array($this->_msgCallback,
525 array(&$this, $err));
526 $err[
'message'] = $msg;
535 if (!is_callable($callback)) {
538 if (is_callable($callback)) {
542 $callback = isset(
$GLOBALS[
'_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?
544 $GLOBALS[
'_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][
'*'];
547 if (is_callable($callback)) {
548 switch(call_user_func($callback, $err)){
549 case PEAR_ERRORSTACK_IGNORE:
552 case PEAR_ERRORSTACK_PUSH:
555 case PEAR_ERRORSTACK_LOG:
558 case PEAR_ERRORSTACK_DIE:
565 array_unshift($this->_errors, $err);
566 if (!isset($this->_errorsByLevel[$err[
'level']])) {
567 $this->_errorsByLevel[$err[
'level']] = array();
569 $this->_errorsByLevel[$err[
'level']][] = &$this->_errors[0];
572 if ($this->_logger ||
$GLOBALS[
'_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {
579 if ($this->_compat && $push) {
580 return $this->
raiseError($msg, $code,
null,
null, $err);
604 $package, $code, $level =
'error', $params = array(),
605 $msg =
false, $repackage =
false, $backtrace =
false
608 if ($s->_contextCallback) {
610 if (function_exists(
'debug_backtrace')) {
611 $backtrace = debug_backtrace();
615 return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
626 if ($this->_logger) {
629 $logger = &
$GLOBALS[
'_PEAR_ERRORSTACK_DEFAULT_LOGGER'];
631 if (is_a($logger,
'Log')) {
633 'exception' => PEAR_LOG_CRIT,
634 'alert' => PEAR_LOG_ALERT,
635 'critical' => PEAR_LOG_CRIT,
636 'error' => PEAR_LOG_ERR,
637 'warning' => PEAR_LOG_WARNING,
638 'notice' => PEAR_LOG_NOTICE,
639 'info' => PEAR_LOG_INFO,
640 'debug' => PEAR_LOG_DEBUG);
641 if (isset($levels[$err[
'level']])) {
642 $level = $levels[$err[
'level']];
644 $level = PEAR_LOG_INFO;
646 $logger->log($err[
'message'], $level, $err);
648 call_user_func($logger, $err);
662 $err = @array_shift($this->_errors);
663 if (!is_null($err)) {
664 @array_pop($this->_errorsByLevel[$err[
'level']]);
665 if (!count($this->_errorsByLevel[$err[
'level']])) {
666 unset($this->_errorsByLevel[$err[
'level']]);
682 if (!isset(
$GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'][$package])) {
685 return $GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
698 return isset($this->_errorsByLevel[$level]);
700 return count($this->_errors);
710 function getErrors($purge =
false, $level =
false)
714 if (!isset($this->_errorsByLevel[$level])) {
717 return $this->_errorsByLevel[$level];
724 $ret = $this->_errorsByLevel[$level];
725 foreach ($this->_errorsByLevel[$level] as $i => $unused) {
727 $this->_errorsByLevel[$level][$i] =
false;
730 $this->_errors = array_filter($this->_errors);
731 unset($this->_errorsByLevel[$level]);
735 $this->_errors = array();
736 $this->_errorsByLevel = array();
749 public static function staticHasErrors($package =
false, $level =
false)
752 if (!isset(
$GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'][$package])) {
755 return $GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);
757 foreach (
$GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
758 if ($obj->hasErrors($level)) {
777 $purge =
false, $level =
false, $merge =
false,
778 $sortfunc = array(
'PEAR_ErrorStack',
'_sortErrors')
781 if (!is_callable($sortfunc)) {
782 $sortfunc = array(
'PEAR_ErrorStack',
'_sortErrors');
784 foreach (
$GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
785 $test =
$GLOBALS[
'_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);
788 $ret = array_merge($ret, $test);
790 $ret[$package] = $test;
795 usort($ret, $sortfunc);
806 if ($a[
'time'] == $b[
'time']) {
809 if ($a[
'time'] < $b[
'time']) {
828 public static function getFileLine($code, $params, $backtrace =
null)
830 if ($backtrace ===
null) {
835 if (!isset($backtrace[1])) {
838 while (isset($backtrace[$functionframe][
'function']) &&
839 $backtrace[$functionframe][
'function'] ==
'eval' &&
840 isset($backtrace[$functionframe + 1])) {
844 if (isset($backtrace[$frame])) {
845 if (!isset($backtrace[$frame][
'file'])) {
848 $funcbacktrace = $backtrace[$functionframe];
849 $filebacktrace = $backtrace[$frame];
850 $ret = array(
'file' => $filebacktrace[
'file'],
851 'line' => $filebacktrace[
'line']);
853 if (strpos($filebacktrace[
'file'],
'(') &&
854 preg_match(
';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace[
'file'],
856 $ret[
'file'] = $matches[1];
857 $ret[
'line'] = $matches[2] + 0;
859 if (isset($funcbacktrace[
'function']) && isset($backtrace[1])) {
860 if ($funcbacktrace[
'function'] !=
'eval') {
861 if ($funcbacktrace[
'function'] ==
'__lambda_func') {
862 $ret[
'function'] =
'create_function() code';
864 $ret[
'function'] = $funcbacktrace[
'function'];
868 if (isset($funcbacktrace[
'class']) && isset($backtrace[1])) {
869 $ret[
'class'] = $funcbacktrace[
'class'];
903 public static function getErrorMessage(&$stack, $err, $template =
false)
906 $mainmsg = $template;
908 $mainmsg = $stack->getErrorMessageTemplate($err[
'code']);
910 $mainmsg = str_replace(
'%__msg%', $err[
'message'], $mainmsg);
911 if (is_array($err[
'params']) &&
count($err[
'params'])) {
912 foreach ($err[
'params'] as $name => $val) {
913 if (is_array($val)) {
915 $val = @implode(
', ', $val);
917 if (is_object($val)) {
918 if (method_exists($val,
'__toString')) {
919 $val = $val->__toString();
922 'warning', array(
'obj' => get_class($val)),
923 'object %obj% passed into getErrorMessage, but has no __toString() method');
927 $mainmsg = str_replace(
'%' . $name .
'%', $val, $mainmsg);
939 if (!isset($this->_errorMsgs[$code])) {
942 return $this->_errorMsgs[$code];
961 $this->_errorMsgs = $template;
972 require_once
'PEAR.php';
973 $args = func_get_args();
974 return call_user_func_array(array(
'PEAR',
'raiseError'), $args);
978 $stack->pushCallback(array(
'PEAR_ErrorStack',
'_handleError'));