Location: PHPKode > projects > ZZ/OSS Installer > zic-1.1.0dev1/installer/lib/HTML/Progress/Error/Raise.php
<?php
/**
 * Error Management for PEAR
 *
 * The Error_Raise static class contains tremendously simple and powerful
 * error management based on error codes.
 * @package Error_Raise
 * @author Greg Beaver <hide@address.com>
 * @version 0.2.2
 */
/**
 * for PEAR_Error class
 */
require_once 'PEAR.php';
/**
 * Pre-defined Error classes for Error_Raise
 */
require_once 'HTML/Progress/Error/Raise/Error.php';
/**
 * Utility static class
 */
require_once 'HTML/Progress/Error/Util.php';

/**
 * Repository for error message generations
 * @see Error_Raise::setErrorMsgGenerator()
 * @global array $GLOBALS['_ERROR_RAISE_MSGS']
 * @name $_ERROR_RAISE_MSGS
 * @access private
 */
$GLOBALS['_ERROR_RAISE_MSGS'] =
    array(
        'error_raise' => array('Error_Raise', '_getErrorMessage'),
    );

/**
 * Repository for context file/line number generators
 *
 * @see Error_Raise::setContextGrabber()
 * @global array $GLOBALS['_ERROR_RAISE_CONTEXTGRABBER']
 * @name $_ERROR_RAISE_CONTEXTGRABBER
 * @access private
 */
$GLOBALS['_ERROR_RAISE_CONTEXTGRABBER'] =
    array(
        'error_raise' => array('Error_Util', '_getFileLine'),
    );

/**
 * Stack used to control error raising
 *
 * This stack contains disabled callbacks.  It is an array of either '*' for
 * all callbacks, or an array of package names
 * @see Error_Raise::disableErrorCallbacks()
 * @access private
 * @global array $GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS']
 * @name $_ERROR_RAISE_DISABLED_CALLBACKS
 */
$GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS'] = array();
/**#@+
 * Error message display constants
 */
/**
 * Plain text error messages
 */
define('ERROR_RAISE_TEXT', 1);
/**
 * html error messages
 */
define('ERROR_RAISE_HTML', 2);
/**
 * ansi (console) error messages
 */
define('ERROR_RAISE_ANSI', 3);
/**#@-*/

/**
 * Error Raise - central coordination for generation of error messages
 *
 * To use, simply call Error_Raise::initialize() with the package name
 * and a function name for generation of error messages.  There is no need
 * to instantiate the Error_Raise or define any error classes, unless you
 * need extra functionality in the error message context information (see
 * {@link setContextGrabber()} for details).
 *
 * To create an error, you must:
 * - define an error code
 * - create a function that maps this error code to a message
 * - call Error_Raise::initialize
 * - call one of the error creators with the package name and any additional
 *   parameters unique to this error instance
 *
 * If your package is named "mypackage", then create errors, warnings, notices,
 * or exceptions by error code using Error_Raise::error('MyPackage', CODE),
 * Error_Raise::warning('MyPackage', CODE), etc.  If you wish to use non-standard
 * error types for your own debugging purposes like "debug" or "information",
 * simply use {@link raise()} like Error_Raise::raise('MyPackage', CODE, 'debug');
 *
 * You can pass additional information in an associative array.
 *
 * <code>
 * Error_Raise::notice('MyPackage', CODE,
 *     array('name' => $aditional, 'otherstuff' => $another));
 * </code>
 *
 * With this system, you can use {@link Error_Raise::sprintfErrorMessage()} in
 * your error message generation function.
 *
 * The strength of this system is easy internationalization and other benefits.
 * Different functions can be defined to return error messages, and even an
 * end-user can define a different error-message generation function for their
 * own purposes, without modification to the original source.
 *
 * In addition, unique error messages are generated for every package,
 * guaranteed.  Used in conjunction with {@tutorial Error_Handler.pkg Error_Handler}, this can be
 * used in more complicated packages and applications to handle errors from
 * multiple packages, propagate errors and even transmute them, and log them or
 * do other advanced processing.
 *
 * For those concerned about performance, all of this extra functionality is
 * only 8% slower than the PEAR::raiseError() method.  In other words, the
 * difference is negligible, and allows a huge jump in error handling.
 * @see initialize()
 * @tutorial Error_Raise.pkg
 * @package Error_Raise
 * @version 0.2.2
 * @author Greg Beaver <hide@address.com>
 * @static
 */
class Error_Raise {
    /**
     * Initialize error raising for a package
     *
     * Use this method to assign an error message handler to a package.  Note:
     * This is an alias to {@link set ErrorMsgGenerator()}
     *
     * As an example, here is a simple Error_Raise usage:
     *
     * <code>
     * <?php
     * // define error constants for package foo
     * define("FOO_ERROR_NOT_NUMBER", 1);
     * define("FOO_ERROR_NOT_STRING", 2);
     *
     * /**
     *  * Error message generator for package Foo
     *  {@*}
     * function getFooMsg($code, $args, $state)
     * {
     *     $msgs = array(
     *        FOO_ERROR_NOT_NUMBER => 'parameter %p% is a %type%, not a number',
     *        FOO_ERROR_NOT_STRING => 'parameter %p% is a %type%, not a string',
     *     );
     *     if (isset($msgs[$code])) {
     *         $message = $msgs[$code];
     *     } else {
     *         $message = 'Code ' . $code . ' is not a valid error code';
     *     }
     *     return Error_Raise::sprintfErrorMessageWithState(
     *        $message, $args, $state);
     * }
     *
     * // initialize error creation
     * Error_Raise::initialize('foo', 'getFooMsg');
     * // that's it!  Now you can do this any of these:
     * Error_Raise::warning('foo', FOO_ERROR_NOT_STRING,
     *    array('p' => 'bar', 'type' => 'object'));
     * Error_Raise::notice('foo', FOO_ERROR_NOT_STRING,
     *    array('p' => 'bar', 'type' => 'object'));
     * Error_Raise::exception('foo', FOO_ERROR_NOT_NUMBER,
     *    array('p' => 'bar', 'type' => 'object'));
     * $e = Error_Raise::error('foo', FOO_ERROR_NOT_NUMBER,
     *    array('p' => 'bar', 'type' => 'object'));
     * echo $e->getMessage();
     * // displays 'foo error : parameter bar is a object, not a number'
     * echo $e->getMessage(ERROR_RAISE_HTML);
     * // displays '<strong>foo error :</strong> parameter <strong>bar</strong>
     * // is a <strong>object</strong>, not a number
     * ?>
     * </code>
     * @param string package name
     * @param array|string call_user_func_array-compatible function/method
     *
     *                     This function name can be either be a
     *                     global function (string), static class method
     *                     array(classname, method), or object method
     *                     array(&$obj, method).  Be sure to assign by
     *                     reference in PHP 4
     * @static
     */
    function initialize($package, $errorMsgGenerator)
    {
        return Error_Raise::setErrorMsgGenerator($package, $errorMsgGenerator);
    }
    
    /**
     * Create a notice from the error code
     * @param string package name
     * @param integer error code
     * @param array associative array of error-specific data.  This can be
     *        anything.  When used with {@link sprintfErrorMessage()}, it will
     *        allow extremely configurable error messages.
     * @throws Error_Raise::ERROR_RAISE_ERROR_INVALID_INPUT
     * @static
     */
    function notice($package, $code, $args = array())
    {
        /*                 validate input                  */
        if (!is_int($code)) {
            return Error_Raise::exception('error_raise', ERROR_RAISE_ERROR_INVALID_INPUT,
                array('var' => '$code',
                      'was' => gettype($code),
                      'expected' => 'int',
                      'paramnum' => 2));
        }
        if (!is_string($package)) {
            return Error_Raise::exception('error_raise',
                ERROR_RAISE_ERROR_INVALID_INPUT,
                array('was' => gettype($package), 'expected' => 'string', 
                      'param' => '$package', 'paramnum' => 1));
        }
        /*                 done validate input                  */
        $packageclass = $package . '_error';
        // create the error class if necessary
        if (!class_exists($packageclass)) {
            $packageclass = 'error_raise_error';
        }
        $mode = 0;
        $extracallback = null;
        if (isset($GLOBALS['_PEAR_default_error_mode']) &&
              ($GLOBALS['_PEAR_default_error_mode'] & PEAR_ERROR_CALLBACK)) {
            $mode |= $GLOBALS['_PEAR_default_error_mode'];
            $extracallback = $GLOBALS['_PEAR_default_error_options'];
        }
        // verify that packages with disabled callbacks don't have
        // PEAR_ERROR_CALLBACK or PEAR_ERROR_TRIGGER as part of the mode
        if (!count($disabledCallbacks = $GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS'])) {
            if ($disabledCallbacks == '*') {
                $mode &= ~(PEAR_ERROR_CALLBACK | PEAR_ERROR_TRIGGER);
            } else {
                if (in_array(strtolower($package), $disabledCallbacks)) {
                    $mode &= ~(PEAR_ERROR_CALLBACK | PEAR_ERROR_TRIGGER);
                }
            }
        }
        $backtrace = null;
        if (function_exists('debug_backtrace')) {
            $backtrace = debug_backtrace();
        }
        
        return new $packageclass($package, 'notice', $code, $args, $mode,
            $extracallback, $backtrace, false);
    }

    /**
     * Create a warning from the error code
     * @param string package name
     * @param integer error code
     * @param array associative array of error-specific data.  This can be
     *        anything.  When used with {@link sprintfErrorMessage()}, it will
     *        allow extremely configurable error messages.
     * @throws Error_Raise::ERROR_RAISE_ERROR_INVALID_INPUT
     * @static
     */
    function warning($package, $code, $args = array())
    {
        /*                 validate input                  */
        if (!is_int($code)) {
            return Error_Raise::exception('error_raise', ERROR_RAISE_ERROR_INVALID_INPUT,
                array('var' => '$code',
                      'was' => gettype($code),
                      'expected' => 'int',
                      'paramnum' => 2));
        }
        if (!is_string($package)) {
            return Error_Raise::exception('error_raise',
                ERROR_RAISE_ERROR_INVALID_INPUT,
                array('was' => gettype($package), 'expected' => 'string', 
                      'param' => '$package', 'paramnum' => 1));
        }
        /*                 done validate input                  */
        $packageclass = $package . '_error';
        // use the existing error class if possible
        if (!class_exists($packageclass)) {
            $packageclass = 'error_raise_error';
        }
        $mode = 0;
        $extracallback = null;
        if (isset($GLOBALS['_PEAR_default_error_mode']) &&
              ($GLOBALS['_PEAR_default_error_mode'] & PEAR_ERROR_CALLBACK)) {
            $mode |= $GLOBALS['_PEAR_default_error_mode'];
            $extracallback = $GLOBALS['_PEAR_default_error_options'];
        }
        // verify that packages with disabled callbacks don't have
        // PEAR_ERROR_CALLBACK or PEAR_ERROR_TRIGGER as part of the mode
        if (!count($disabledCallbacks = $GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS'])) {
            if ($disabledCallbacks == '*') {
                $mode &= ~(PEAR_ERROR_CALLBACK | PEAR_ERROR_TRIGGER);
            } else {
                if (in_array(strtolower($package), $disabledCallbacks)) {
                    $mode &= ~(PEAR_ERROR_CALLBACK | PEAR_ERROR_TRIGGER);
                }
            }
        }
        $backtrace = null;
        if (function_exists('debug_backtrace')) {
            $backtrace = debug_backtrace();
        }
        
        return new $packageclass($package, 'warning', $code, $args, $mode,
            $extracallback, $backtrace, false);
    }

    /**
     * Create an error from the error code
     * @param string package name
     * @param integer error code
     * @param array associative array of error-specific data.  This can be
     *        anything.  When used with {@link sprintfErrorMessage()}, it will
     *        allow extremely configurable error messages.
     * @throws Error_Raise::ERROR_RAISE_ERROR_INVALID_INPUT
     * @static
     */
    function error($package, $code, $args = array())
    {
        /*                 validate input                  */
        if (!is_int($code)) {
            return Error_Raise::exception('error_raise', ERROR_RAISE_ERROR_INVALID_INPUT,
                array('var' => '$code',
                      'was' => gettype($code),
                      'expected' => 'int',
                      'paramnum' => 2));
        }
        if (!is_string($package)) {
            return Error_Raise::exception('error_raise',
                ERROR_RAISE_ERROR_INVALID_INPUT,
                array('was' => gettype($package), 'expected' => 'string', 
                      'param' => '$package', 'paramnum' => 1));
        }
        /*                 done validate input                  */
        $packageclass = $package . '_error';
        // use the existing error class if possible
        if (!class_exists($packageclass)) {
            $packageclass = 'error_raise_error';
        }
        $mode = 0;
        $extracallback = null;
        if (isset($GLOBALS['_PEAR_default_error_mode']) &&
              ($GLOBALS['_PEAR_default_error_mode'] & PEAR_ERROR_CALLBACK)) {
            $mode |= $GLOBALS['_PEAR_default_error_mode'];
            $extracallback = $GLOBALS['_PEAR_default_error_options'];
        }
        // verify that packages with disabled callbacks don't have
        // PEAR_ERROR_CALLBACK or PEAR_ERROR_TRIGGER as part of the mode
        if (!count($disabledCallbacks = $GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS'])) {
            if ($disabledCallbacks == '*') {
                $mode &= ~(PEAR_ERROR_CALLBACK | PEAR_ERROR_TRIGGER);
            } else {
                if (in_array(strtolower($package), $disabledCallbacks)) {
                    $mode &= ~(PEAR_ERROR_CALLBACK | PEAR_ERROR_TRIGGER);
                }
            }
        }
        $backtrace = null;
        if (function_exists('debug_backtrace')) {
            $backtrace = debug_backtrace();
        }
        
        return new $packageclass($package, 'error', $code, $args, $mode,
            $extracallback, $backtrace, false);
    }

    /**
     * Create an exception from the error code
     * @param string package name
     * @param integer error code
     * @param array associative array of error-specific data.  This can be
     *        anything.  When used with {@link sprintfErrorMessage()}, it will
     *        allow extremely configurable error messages.
     * @throws Error_Raise::ERROR_RAISE_ERROR_INVALID_INPUT
     * @static
     */
    function exception($package, $code, $args = array())
    {
        /*                 validate input                  */
        if (!is_int($code)) {
            return Error_Raise::exception('error_raise', ERROR_RAISE_ERROR_INVALID_INPUT,
                array('var' => '$code',
                      'was' => gettype($code),
                      'expected' => 'int',
                      'paramnum' => 2));
        }
        if (!is_string($package)) {
            return Error_Raise::exception('error_raise',
                ERROR_RAISE_ERROR_INVALID_INPUT,
                array('was' => gettype($package), 'expected' => 'string', 
                      'param' => '$package', 'paramnum' => 1));
        }
        /*                 done validate input                  */
        $packageclass = $package . '_error';
        // use the existing error class if possible
        if (!class_exists($packageclass)) {
            $packageclass = 'error_raise_error';
        }
        $mode = 0;
        $extracallback = null;
        if (isset($GLOBALS['_PEAR_default_error_mode']) &&
              ($GLOBALS['_PEAR_default_error_mode'] & PEAR_ERROR_CALLBACK)) {
            $mode |= $GLOBALS['_PEAR_default_error_mode'];
            $extracallback = $GLOBALS['_PEAR_default_error_options'];
        }
        // verify that packages with disabled callbacks don't have
        // PEAR_ERROR_CALLBACK or PEAR_ERROR_TRIGGER as part of the mode
        if (!count($disabledCallbacks = $GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS'])) {
            if ($disabledCallbacks == '*') {
                $mode &= ~(PEAR_ERROR_CALLBACK | PEAR_ERROR_TRIGGER);
            } else {
                if (in_array(strtolower($package), $disabledCallbacks)) {
                    $mode &= ~(PEAR_ERROR_CALLBACK | PEAR_ERROR_TRIGGER);
                }
            }
        }
        $backtrace = null;
        if (function_exists('debug_backtrace')) {
            $backtrace = debug_backtrace();
        }
        
        return new $packageclass($package, 'exception', $code, $args, $mode,
            $extracallback, $backtrace, false);
    }
    
    /**
     * Return an error object
     *
     * For more control, call this static function directly, otherwise use
     * one of the shorthand methods.
     * @param string package name throwing the error
     * @param integer error code
     * @param string error type
     * @param false|Error_Raise_Error parent error, for cascading
     * @param integer error mode, see {@link PEAR.php}
     * @param string|array callback function for PEAR_ERROR_CALLBACK mode
     * @return Error_Raise_Error
     * @throws ERROR_RAISE_ERROR_INVALID_INPUT
     * @static
     */
    function raise($package, $code, $errorType, $args, $mode = null,
        $extracallback = null, $parent = false)
    {
        /*                 validate input                  */
        if (!is_int($code)) {
            return Error_Raise::exception('error_raise', ERROR_RAISE_ERROR_INVALID_INPUT,
                array('var' => '$code',
                      'was' => gettype($code),
                      'expected' => 'int',
                      'paramnum' => 2));
        }
        if (!is_string($package)) {
            return Error_Raise::exception('error_raise', ERROR_RAISE_ERROR_INVALID_INPUT,
                array('var' => '$package',
                      'was' => gettype($package),
                      'expected' => 'string',
                      'paramnum' => 1));
        }
        if (!is_string($errorType)) {
            return Error_Raise::exception('error_raise', ERROR_RAISE_ERROR_INVALID_INPUT,
                array('paramnum' => 3,
                      'var' => '$errorType',
                      'was' => gettype($errorType),
                      'expected' => 'string'));
        }
        $errorType = strtolower($errorType);
        /*                 done validate input                  */
        // create the error class if necessary
        $errorClass = $package . '_error';
        // use the existing error class if possible
        if (!class_exists($errorClass)) {
            $errorClass = 'error_raise_error';
        }
        
        if (isset($GLOBALS['_PEAR_default_error_mode']) &&
              ($GLOBALS['_PEAR_default_error_mode'] & PEAR_ERROR_CALLBACK)) {
            $mode |= $GLOBALS['_PEAR_default_error_mode'];
            $extracallback = $GLOBALS['_PEAR_default_error_options'];
        }
        // verify that packages with disabled callbacks don't have
        // PEAR_ERROR_CALLBACK or PEAR_ERROR_TRIGGER as part of the mode
        if (count($disabledCallbacks = $GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS'])) {
            if ($disabledCallbacks == '*') {
                $mode &= ~(PEAR_ERROR_CALLBACK | PEAR_ERROR_TRIGGER);
            } else {
                if (in_array(strtolower($package), $disabledCallbacks)) {
                    $mode &= ~(PEAR_ERROR_CALLBACK | PEAR_ERROR_TRIGGER);
                }
            }
        }
        $backtrace = null;
        if (function_exists('debug_backtrace')) {
            $backtrace = debug_backtrace();
        }
        
        return new $errorClass($package, $errorType, $code, $args, $mode,
            $extracallback, $backtrace, false);
    }
    
    /**
     * Determine if an error was triggered by a package or group of packages
     *
     * This will trigger a PHP warning if parameters are invalid
     * @param Error_Raise_Error
     * @param string|array single package name, or list of package names
     * @return boolean
     */
    function isPackageError($error, $package)
    {
        if (is_string($package)) {
            $package = array(strtolower($package));
        }
        if (!is_a($error, 'Error_Raise_Error')) {
            return false;
        }
        if (array_walk($package, create_function('&$s','$s = strtolower($s);'))) {
            return in_array($error->_package, $package);
        }
        return false;
    }
    
    /**
     * Determine whether input is an error class with level "error"
     *
     * use PEAR::isError() to determine if a class is an error class.  This
     * static method is only for determining the error level of a class
     * @static
     * @param mixed
     * @return boolean true if $obj is an Error_Raise_Error and is type error
     */
    function isError($obj)
    {
        return is_a($obj, 'error_raise_error') && $obj->_type == 'error';
    }
    
    
    /**
     * Determine whether input is an error class with level "exception"
     *
     * use PEAR::isError() to determine if a class is an error class.  This
     * static method is only for determining the error level of a class
     * @static
     * @param mixed
     * @return boolean true if $obj is an Error_Raise_Error and is type exception
     */
    function isException($obj)
    {
        return is_a($obj, 'error_raise_error') && $obj->_type == 'exception';
    }
    
    
    /**
     * Determine whether input is an error class with level "notice"
     *
     * use PEAR::isError() to determine if a class is an error class.  This
     * static method is only for determining the error level of a class
     * @static
     * @param mixed
     * @return boolean true if $obj is an Error_Raise_Error and is type notice
     */
    function isNotice($obj)
    {
        return is_a($obj, 'error_raise_error') && $obj->_type == 'notice';
    }
    
    
    /**
     * Determine whether input is an error class with level "warning"
     *
     * use PEAR::isError() to determine if a class is an error class.  This
     * static method is only for determining the error level of a class
     * @static
     * @param mixed
     * @return boolean true if $obj is an Error_Raise_Error and is type warning
     */
    function isWarning($obj)
    {
        return is_a($obj, 'error_raise_error') && $obj->_type == 'warning';
    }
    
    /**
     * Get the list of packages for which callbacks are temporarily disabled
     *
     * @see disableErrorCallbacks
     * @return false|array|*
     */
    function getDisabledCallbacks()
    {
        if (!count($GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS'])) {
            return false;
        }
        return $GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS']
            [count($GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS']) - 1];
    }
    
    /**
     * Temporarily disable any error callbacks/trigger_error.
     *
     * To temporarily disable callback functions in order to suppress any
     * error reporting of internal errors, use this static method.  To
     * selectively disable a short list of packages, and allow others to inform
     * callbacks of their creation, pass in an array of the names of packages
     * to disable errors for.
     *
     * This is similar to PEAR::expectError(), except that only global
     * error-handling is affected
     * @param array list of packages to disable error callbacks for
     * @throws Error_Raise_Exception::ERROR_RAISE_ERROR_INVALID_INPUT
     * @return true|Error_Raise_Exception
     * @static
     */
    function disableErrorCallbacks($packages = array())
    {
        if (!is_array($packages) && !is_string($packages)) {
            return Error_Raise::exception('error_raise',
                ERROR_RAISE_ERROR_INVALID_INPUT,
                array('was' => gettype($packages), 'expected' => 'array|string',
                      'param' => '$packages', 'paramnum' => 1));
        }
        if (is_string($packages)) {
            $packages = array($packages);
        }
        $newpack = array();
        foreach($packages as $i => $package) {
            if (!is_string($package)) {
                return Error_Raise::exception('error_raise',
                ERROR_RAISE_ERROR_INVALID_INPUT,
                array('was' => gettype($package), 'expected' => 'string',
                      'param' => '$packages[' . $i . ']', 'paramnum' => 1));
            }
            $newpack[] = strtolower($package);
        }
        if (!count($newpack)) {
            array_push($GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS'], '*');
        } else {
            array_push($GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS'], $newpack);
        }
        return true;
    }
    
    /**
     * Re-enable callbacks that were temporarily disabled with
     * {@link disableErrorCallbacks()}
     */
    function reenableErrorCallbacks()
    {
        array_pop($GLOBALS['_ERROR_RAISE_DISABLED_CALLBACKS']);
    }
    
    /**
     * Change the error message generation method from one set in the
     * constructor
     *
     * If later logic requires the use of different error messages for a
     * package, use this static method to change the message generator.
     * @return true|Error_Raise_Error
     * @param string package name
     * @param string|array callback
     * @static
     */
    function setErrorMsgGenerator($package, $errorMsgGenerator)
    {
        if ($errorMsgGenerator) {
            $package = strtolower($package);
            Error_Raise::disableErrorCallbacks();
            $e = Error_Util::_validCallback($errorMsgGenerator);
            Error_Raise::reenableErrorCallbacks();
            if (PEAR::isError($e)) {
                return $e->rePackageError('Error_Raise', 'error',
                    ERROR_RAISE_ERROR_INVALID_ERRMSGGEN,
                    array('package' => $package));
            }
            $GLOBALS['_ERROR_RAISE_MSGS'][$package] = $errorMsgGenerator;
            return true;
        }
    }
    
    /**
     * Set the function/method used to retrieve context information
     * for an error, like the file and line number that generated an error.
     *
     * In most cases, the file or line number is the file/line returned from
     * the debug_backtrace() called at the error's creation.  In some cases,
     * the error/warning/notice occurs when processing another file, and this
     * function can be used to set the callback that should be used to
     * retrieve this information.
     *
     * A function passed to setContextGrabber() must return an associative
     * array of values.  These values will be assigned to properties of a new
     * error object created by {@link raise()}.  In this way, the properties can
     * be used by {@link Error_Raise_Error::getErrorPrefix()} to generate
     * context-specific information for each error.
     *
     * An example of a custom context grabber:
     *
     * <code>
     * class doesDB {
     *     /**
     *      * We ignore the backtrace and instead use DB-specific information
     *      * @param array debug_backtrace() output
     *      * @param integer backtrace frame to use
     *      {@*}
     *     function grabContext($trace, $frame)
     *     {
     *         $return = array(
     *            '_db' => $this->_databaseName,
     *            '_table' => $this->_tableName,
     *            '_queryPos' => $this->_queryPos,);
     *     }
     * }
     * </code>
     *
     * Then, you can use this context information in a custom implementation
     * of {@link Error_Raise_Error::getErrorPrefix()}
     *
     * <code>
     * $db = &new doesDB;
     * Error_Raise::setContextGrabber('myDB', array(&$db, 'grabContext'));
     * ...
     * class myDB_Error extends Error_Raise_Error {
     *     function getErrorPrefix($state = ERROR_RAISE_TEXT)
     *     {
     *         $prefix = $this->getPackage() . ' ' . $this->getErrorType();
     *         if (isset($this->_db)) {
     *             $prefix .= ' in database "' . $this->_db . '"';
     *         }
     *         if (isset($this->_table)) {
     *             $prefix .= ', ' . $this->_table;
     *         }
     *         if (isset($this->_queryPos)) {
     *             $prefix .= ' query position ' . $this->_queryPos;
     *         }
     *         $prefix .= ' : ';
     *     }
     * }
     * </code>
     * @param string package name
     * @param string|array
     * @static
     */
    function setContextGrabber($package, $fileline)
    {
        $package = strtolower($package);
        $GLOBALS['_ERROR_RAISE_CONTEXTGRABBER'][$package] = $fileline;
        return true;
    }
    
    /**
     * Get an Error_Raise error message from a code
     *
     * This is the error message generator for the Error_Raise package, and
     * should not be used by other packages.  It can be used as an example
     * of one way to generate an error message
     * @access private
     * @return string error message from error code
     * @param integer
     * @param array
     * @static
     */
    function _getErrorMessage($code, $args = array(), $state = ERROR_RAISE_TEXT)
    {
        if (!is_array($args)) {
            return 'Error: $args passed to Error_Raise::_getErrorMessage is '.
                'not an array but a '.gettype($args);
        }
        $messages =
        array(
            ERROR_RAISE_ERROR_CLASS_DOESNT_EXIST =>
                'class "%cl%" does not exist',
            ERROR_RAISE_ERROR_CODENOMSG =>
                'package "%package%" has no registered error message '
                    . 'generator',
            ERROR_RAISE_ERROR_ALREADY_INITIALIZED =>
                'package "%package%" has already been initialized',
            ERROR_RAISE_ERROR_INVALID_INPUT =>
                'invalid input, parameter #%paramnum% '
                    . '"%var%" was expecting '
                    . '"%expected%", instead got "%was%"',
            ERROR_RAISE_ERROR_INVALID_ERROR_CLASS =>
                'error class "%class%" in package '
                    . '"%package%," error type '
                    . '"%type%" does not descend from '
                    . 'Error_Raise_Error.  Use '
                    . 'PEAR::raiseError() for normal PEAR_Error classes',
            ERROR_RAISE_ERROR_INVALID_ERRMSGGEN =>
                'Invalid callback passed to setErrorMsgGenerator() for package'
                    . ' %package%',
            ERROR_RAISE_ERROR_INVALID_CONTEXT_GRABBER =>
                'An invalid callback was passed as a context grabber for '
                    . 'package %package%',
            ERROR_RAISE_ERROR_INVALID_CONTEXTGRABBER_RETURN =>
                'The context grabber for package %package% did not return an '
                    . 'array, but instead returned a %type%',
             );
        if (is_int($code) && isset($messages[$code])) {
            $msg = $messages[$code];
            return Error_Raise::sprintfErrorMessageWithState($msg,
                $args, $state);
        } else {
            return 'Error: code ' . $code . ' not found';
        }
    }
    
    /**
     * Simple utility function for replacing variables with values in an error
     * message template
     *
     * This simple str_replace-based function can be used to have an
     * order-independent sprintf, so error messages can be passed in
     * with different grammar ordering, or other possibilities without
     * changing the source code.
     *
     * In addition, if the argument is an object and has a toString() method,
     * it will be called in order to transform the object into viewable text.
     * If it is an array, the values will be joined together by commas
     *
     * Variables should simply be surrounded by % as in %varname%
     * @param string error message template
     * @param array associative array of template var -> message text
     * @see sprintfErrorMessageWithState
     * @static
     */
    function sprintfErrorMessage($msg, $args)
    {
        if (is_array($args)) {
            foreach($args as $name => $value) {
                $val = $value;
                if (is_object($value) && method_exists($value, 'tostring')) {
                    $val = $value->toString();
                }
                if (is_array($value)) {
                    $i = 0;
                    $val = '';
                    foreach($value as $item) {
                        if ($i++ > 0) {
                            $val .= ', ';
                        }
                        $val .= $item;
                    }
                }
                $msg = str_replace("%$name%", $val, $msg);
            }
        }
        return $msg;
    }
    
    /**
     * Simple utility function for replacing variables with values in an error
     * message template, with special formatting for state.
     *
     * This simple str_replace-based function can be used to have an
     * order-independent sprintf, so error messages can be passed in
     * with different grammar ordering, or other possibilities without
     * changing the source code.
     *
     * In addition, if the argument is an object and has a toString() method,
     * it will be called in order to transform the object into viewable text.
     * If it is an array, the values will be joined together by commas
     *
     * Variables should simply be surrounded by % as in %varname%
     * @param string error message template
     * @param array associative array of template var -> message text
     * @param ERROR_RAISE_TEXT|ERROR_RAISE_ANSI|ERROR_RAISE_HTML
     * @see sprintfErrorMessage
     * @static
     */
    function sprintfErrorMessageWithState($msg, $args, $state)
    {
        if (is_array($args)) {
            foreach($args as $name => $value) {
                $val = $value;
                if (is_object($value) && method_exists($value, 'tostring')) {
                    $val = $value->toString();
                }
                if (is_array($value)) {
                    $i = 0;
                    $val = '';
                    foreach($value as $item) {
                        if ($i++ > 0) {
                            $val .= ', ';
                        }
                        $val .= $item;
                    }
                }
                if ($state == ERROR_RAISE_ANSI) {
                    $msg = str_replace("%$name%",
                        '%r%U%%' . $val . '%%U%r', $msg);
                } elseif ($state == ERROR_RAISE_HTML) {
                    $msg = str_replace("%$name%", 
                        '<strong>' . $val . '</strong>', $msg);
                } else {
                    $msg = str_replace("%$name%", $val, $msg);
                }
            }
        }
        if ($state == ERROR_RAISE_HTML) {
            return nl2br($msg);
        }
        return $msg;
    }
}

if (!function_exists('is_a')) {
/**
 * @ignore
 */
function is_a($obj, $classname)
{
    return (get_class($obj) == strtolower($classname)) ||
        is_subclass_of($obj, $classname);
}
}
?>
Return current item: ZZ/OSS Installer