Location: PHPKode > projects > ZZ/OSS Installer > zic-1.1.0dev1/installer/lib/HTML/Progress/Error/Util.php
<?php
/**
 * Utility static class
 * @package Error_Raise
 * @version 0.2.2
 * @author Greg Beaver hide@address.com
 */
/**
 * Error used if a class passed to initialize hasn't been defined yet
 *
 * {@link initialize()} allows
 */
define('ERROR_UTIL_ERROR_CLASS_DOESNT_EXIST', 1);
/**
 * Error used if a method doesn't exist in a callback passed in
 */
define('ERROR_UTIL_ERROR_METHOD_DOESNT_EXIST', 2);
/**
 * Error used if a function doesn't exist in a callback passed in
 */
define('ERROR_UTIL_ERROR_FUNCTION_DOESNT_EXIST', 3);
/**
 * Error used when parameters to functions don't match expected types
 */
define('ERROR_UTIL_ERROR_INVALID_INPUT', 4);
/**
 * Error used when an internal function is passed as a callback - this is never
 * allowed.
 */
define('ERROR_UTIL_ERROR_INTERNAL_FUNCTION', 5);
/**
 * Utility functions for Error display
 *
 * This class is used for advanced retrieval of context information, and for
 * callback validation.  It also has a few miscellaneous functions for processing
 * display of variables.
 * @package Error_Raise
 * @version 0.2.2
 * @author Greg Beaver hide@address.com
 * @static
 */
class Error_Util {
    /**
     * Extracted from {@link http://mojavelinux.com/forum/viewforum.php?f=4}
     * originally by Dan Allen
     * @param string full path to source file that triggered a PHP error
     * @param string line number of error
     * @static
     */
    function getErrorContext($file, $line, $contextLines = 5)
    {
        if (!file_exists($file) || !is_readable($file)) {
            return array(
                'start'        => 0,
                'end'        => 0,
                'source'    => '',
                'variables'    => array(),
            );
        }

        $sourceLines = file($file);
        $offset = max($line - 1 - $contextLines, 0);
        $numLines = 2 * $contextLines + 1;
        $sourceLines = array_slice($sourceLines, $offset, $numLines);
        $numLines = count($sourceLines);
        // add line numbers
        foreach ($sourceLines as $index => $line) {
            $sourceLines[$index] = ($offset + $index + 1)  . ': ' . $line;
        }
    
        $source = Error_Util::_addPhpTags(join('', $sourceLines));
        preg_match_all(';\$([[:alnum:]]+);', $source, $matches);
        $variables = array_values(array_unique($matches[1]));
        return array(
            'start'        => $offset + 1,
            'end'        => $offset + $numLines,
            'source'    => $source,
            'variables'    => $variables,
        );
    }

    /**
     * Extracted from {@link http://mojavelinux.com/forum/viewforum.php?f=4}
     * originally by Dan Allen
     * @param array list of variables found in code context
     * @param array list of variables from trigger_error context
     * @param boolean if false, then all variables in $variables will be dumped
     * @param array list of classes to exclude from var_export
     * @param string line number of error
     * @return string|false
     * @static
     */
    function exportVariables($variables, $contextVariables, $strict = true,
        $excludeClasses = array())
    {
        $variableString = '';
        foreach ($variables as $name => $contents) {
            // if we are using strict context and this variable is
            // not in the context, skip it
            if ($strict && !in_array($name, $contextVariables)) {
                continue;
            }

            // if this is an object and the class is in the exclude list, skip it
            if (is_object($contents) && in_array(get_class($contents),
                  $excludeClasses)) {
                continue;
            }

            $variableString .= '$' . $name . ' = ' .
                Error_Util::var_export2($contents, true) . ';' . "\n";
        }

        if (empty($variableString)) {
            return false;
        } else {
            return "\n" . $variableString;
        }
    }
    

    /**
     * Extracted from {@link http://mojavelinux.com/forum/viewforum.php?f=4}
     * originally by Dan Allen
     * @param string string that should be escaped for JS
     * @return string
     * @static
     */
    function escapeJavascript($string)
    {
        return strtr($string, array(
            "\t" => '\\t',
            "\n" => '\\n',
            "\r" => '\\r',
            '\\' => '&#092;',
            "'" => '&#39;'));
    }

    /**
     * Copied from {@link http://www.php.net/strrpos}, comment by
     * DONT SPAM vardges at iqnest dot com
     * @param string full string
     * @param string search string
     * @param integer offset from the start of the string to begin searching
     *                from
     * @static
     */
    function strrpos_str ($string, $searchFor, $startFrom = 0)
    {
        $addLen = strlen ($searchFor);
        $endPos = $startFrom - $addLen;

        while (true) {
            if (($newPos = strpos ($string, $searchFor,
                  $endPos + $addLen)) === false) {
                break;
            }
            $endPos = $newPos;
        }

        return ($endPos >= 0) ? $endPos : false;
    }

    /**
     * Add PHP Tags if necessary to variable context PHP for highlighting
     *
     * Extracted from {@link http://mojavelinux.com/forum/viewforum.php?f=4}
     * originally by Dan Allen
     * @param string source code for context around an error
     * @static
     */
    function _addPhpTags($source)
    {
        $startTag  = '<?php';
        $endTag = '?>';

        if (($pos = strpos($source, $startTag)) !== false) {
            $firstStartPos = $pos;
        } else {
            $firstStartPos = -1;
        }
        if (($pos = strpos($source, $endTag)) !== false) {
            $firstEndPos = $pos;
        } else {
            $firstEndPos = -1;
        }

        // no tags found then it must be solid php since
        // html can't throw a php error
        if ($firstStartPos < 0 && $firstEndPos < 0) {
            return $startTag . "\n" . $source . "\n" . $endTag;
        }

        // found an end tag first, so we are missing a start tag
        if ($firstEndPos >= 0 &&
              ($firstStartPos < 0 || $firstStartPos > $firstEndPos)) {
            $source = $startTag . "\n" . $source;
        }

        $sourceLength = strlen($source);
        if (($pos = Error_Util::strrpos_str($source, $startTag)) !== false) {
            $lastStartPos = $pos;
        } else {
            $lastStartPos = $sourceLength + 1;
        }
        if (($pos = Error_Util::strrpos_str($source, $endTag)) !== false) {
            $lastEndPos = $pos;
        } else {
            $lastEndPos = $sourceLength + 1;
        }

        if ($lastEndPos < $lastStartPos || ($lastEndPos > $lastStartPos
              && $lastEndPos > $sourceLength)) {
            $source .= $endTag;
        }

        return $source;
    }

    /**
     * More advanced var_export for HTML/Javascript, private recursive function
     *
     * Extracted from {@link http://mojavelinux.com/forum/viewforum.php?f=4}
     * originally by Dan Allen
     * @param mixed variable to var_export
     * @param string indentation
     * @param boolean is an array portion of the variable
     * @param integer recursion level
     * @access private
     * @static
     */
    function &_var_export2(&$variable, $arrayIndent = '', $inArray = false,
        $level = 0)
    {
        static $maxLevels = 5, $followObjectReferences = false;
        if ($inArray != false) {
            $leadingSpace = '';
            $trailingSpace = ',' . "\n";
        } else {
            $leadingSpace = $arrayIndent;
            $trailingSpace = '';
        }

        $result = '';
        switch (gettype($variable))
        {
            case 'object':
                if ($inArray && !$followObjectReferences)
                {
                    $result = '*' . get_class($variable) . ' REFERENCE*';
                    $trailingSpace = "\n";
                    break;
                }
            case 'array':
                if ($maxLevels && $level >= $maxLevels) {
                    $result = '** truncated, too much recursion **';
                } else {
                    $result = "\n" . $arrayIndent . 'array (' . "\n";
                    foreach ($variable as $key => $value) {
                        $result .= $arrayIndent . '  ' . (is_int($key)
                          ? $key : ('\'' . 
                          str_replace('\'', '\\\'', $key) . '\'')) . ' => ' . 
                          Error_Util::_var_export2($value,
                            $arrayIndent . '  ', true, $level + 1);
                    }

                    $result .= $arrayIndent . ')';
                }
            break;

            case 'string':
                $result = '\'' . str_replace('\'', '\\\'', $variable) . '\'';
            break;

            case 'boolean':
                $result = $variable ? 'true' : 'false';
            break;

            case 'NULL':
                $result = 'NULL';
            break;

            case 'resource':
                $result = get_resource_type($variable);
            break;

            default:
                $result = $variable;
            break;
        }

        return $leadingSpace . $result . $trailingSpace;
    }

    /**
     * More advanced var_export for HTML/Javascript, private recursive function
     *
     * Extracted from {@link http://mojavelinux.com/forum/viewforum.php?f=4}
     * originally by Dan Allen
     * @param mixed variable to var_export
     * @param boolean prints output by default, set to true to return a string
     * @static
     */
    function var_export2(&$variable, $return = false)
    {
        $result =& Error_Util::_var_export2($variable);
        if ($return) {
            return $result;
        } else {
            echo $result;
        }
    }
    
    /**
     * calls {@link file_exists()} for each value in include_path,
     * then calls {@link is_readable()} when it finds the file.
     *
     * This doesn't really belong here, but is useful
     * @param string
     * @return boolean
     */
    function isIncludeable($filename)
    {
        $ip = get_include_path();
        if (substr(PHP_OS, 0, 3) == 'WIN') {
            $ip = explode(';', $ip);
        } else {
            $ip = explode(':', $ip);
        }
        foreach($ip as $path) {
            if ($a = realpath($path . DIRECTORY_SEPARATOR . $filename)) {
                if (is_readable($a)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Default file/line number grabber function
     *
     * This function uses a backtrace generated from {@link debug_backtrace()}
     * and so will not work at all in PHP < 4.3.0.  The frame should
     * reference the frame that contains the source of the error.  See how
     * raise() implements this in the source code for a very specific idea
     * of how to do this in your own code, if you won't be using one of the
     * standard error-throwing methods
     * @return array|false either array('_file' => file, '_line' => line,
     *         '_function' => function name, '_class' => class name) or
     *         if this doesn't work, then false
     * @param array Results of debug_backtrace()
     * @param integer backtrace frame.
     */
    function _getFileLine($backtrace = null, $frame = 0, $functionframe = 1)
    {
        if (isset($backtrace) && is_array($backtrace) &&
              isset($backtrace[$frame])) {
            if (!isset($backtrace[$frame]['file'])) {
                $frame++;
            }
            $funcbacktrace = $backtrace[$functionframe];
            $filebacktrace = $backtrace[$frame];
            $ret = array('_file' => $filebacktrace['file'],
                         '_line' => $filebacktrace['line']);
            // rearrange for eval'd code or create function errors
            if (preg_match(';^(.*?)\((\d+)\) : (.*?)$;', $filebacktrace['file'],
                  $matches)) {
                $ret['_file'] = $matches[1];
                $ret['_line'] = $matches[2] + 0;
            }
            if (isset($funcbacktrace['function'])) {
                $ret['_function'] = $funcbacktrace['function'];
            }
            if (isset($funcbacktrace['class'])) {
                $ret['_class'] = $funcbacktrace['class'];
            }
            return $ret;
        }
        return false;
    }
    
    function formatStackTrace($trace)
    {
        
    }
    
    /**
     * Parse a backtrace to retrieve the calling frame
     *
     * WARNING: do not attempt to use this in any code outside of
     * Error_Raise::raise(), it just won't work at all
     * @access private
     * @param array debug_backtrace() output from {@link Error_Raise::raise()}
     * @param string warning/error/notice/exception
     * @param Error_Raise_Error error object
     */
    function _parseBacktrace($trace, $errorType, &$error)
    {
        if (!isset($trace[1])) {
            return array(0, 0);
        }
        $functionframe = $frame = 1; // get calling function backtrace
        if (isset($trace[1]['class'])) {
            if (isset($trace[1]['function']) &&
                  $trace[1]['function'] != $errorType) {
                // raise was called directly
                $frame = 0;
            }
            $testclass = $trace[$functionframe]['class'];
            if (str_replace($error->getPackage(), '', $testclass) ==
                '_raise' && isset($trace[$functionframe])) {
                $functionframe++;
            }
        }
        while (isset($trace[$functionframe]['function']) &&
              in_array($trace[$functionframe]['function'],
              array('eval', '__lambda_func')) &&
              isset($trace[$functionframe + 1])) {
            $functionframe++;
        }
        return array($frame, $functionframe);
    }

    /**
     * Verify that $callback is a valid function callback
     *
     * This is used to be absolutely sure a callback is valid before registering
     * it, to avoid later errors on the throwing of an error
     * @param string|array
     * @return true|Error_Raise_Error
     * @throws ERROR_UTIL_ERROR_FUNCTION_DOESNT_EXIST If the callback is a
     *         string and isn't the name of any function
     * @throws ERROR_UTIL_ERROR_INTERNAL_FUNCTION If the callback is the name
     *         of an internal, pre-defined function like "function_exists"
     * @throws ERROR_UTIL_ERROR_INVALID_INPUT If the callback is neither
     *         a string, an array(classname, method), or an array(object, method)
     * @throws ERROR_UTIL_ERROR_METHOD_DOESNT_EXIST if the callback is an
     *         array, and the method is not a method of the class
     * @access private
     */
    function _validCallback($callback)
    {
        static $init = false;
        if (!$init) {
            $init = true;
            Error_Raise::setErrorMsgGenerator('Error_Util',
                array('Error_Util', 'genErrorMessage'));
        }
        if (is_string($callback)) {
            if (!function_exists($callback)) {
                return Error_Raise::exception('Error_Util',
                    ERROR_UTIL_ERROR_FUNCTION_DOESNT_EXIST,
                    array('function' => $callback));
            }
            $a = get_defined_functions();
            if (in_array($callback, $a['internal'])) {
                return Error_Raise::exception('Error_Util',
                    ERROR_UTIL_ERROR_INTERNAL_FUNCTION,
                    array('function' => $callback));
            }
            return true;
        }
        if (is_array($callback)) {
            if (!isset($callback[0]) || !isset($callback[1])) {
                return Error_Raise::exception('Error_Util',
                    ERROR_UTIL_ERROR_INVALID_INPUT,
                    array('expected' => array(0, 1),
                          'was' => array_keys($callback),
                          'var' => 'array_keys($callback)',
                          'paramnum' => 1));
            }
            if (is_string($callback[0])) {
                if (!is_string($callback[1])) {
                    return Error_Raise::exception('Error_Util',
                        ERROR_UTIL_ERROR_INVALID_INPUT,
                        array('expected' => 'string',
                              'was' => gettype($callback[1]),
                              'var' => '$callback[1]',
                              'paramnum' => 1));
                }
                if (!class_exists($callback[0])) {
                    return Error_Raise::exception('Error_Util',
                        ERROR_UTIL_ERROR_CLASS_DOESNT_EXIST,
                        array('class' => $callback[0]));
                }
                if (!in_array(strtolower($callback[1]),
                      get_class_methods($callback[0]))) {
                    return Error_Raise::exception('Error_Util',
                        ERROR_UTIL_ERROR_METHOD_DOESNT_EXIST,
                        array('method' => $callback[1],
                              'class' => $callback[0]));
                }
                return true;
            } elseif (is_object($callback[0])) {
                if (!method_exists($callback[0], $callback[1])) {
                    return Error_Raise::exception('Error_Util',
                        ERROR_UTIL_ERROR_METHOD_DOESNT_EXIST,
                        array('method' => $callback[1],
                              'class' => get_class($callback[0])));
                }
                return true;
            } else {
                return Error_Raise::exception('Error_Util',
                    ERROR_UTIL_ERROR_INVALID_INPUT,
                    array('expected' => array('array', 'string'),
                          'was' => gettype($callback[0]),
                          'var' => '$callback[0]',
                          'paramnum' => 1));
            }
            // is a callback method
            return true;
        }
        return Error_Raise::exception('error_util',
                ERROR_UTIL_ERROR_INVALID_INPUT,
                array('expected' => array('array', 'string'),
                      'was' => gettype($callback),
                      'var' => '$callback',
                      'paramnum' => 1));;
    }
    
    /**
     * Get an error message for Error_Util errors
     * @return string error message from error code
     * @param integer
     * @param array
     * @static
     */
    function genErrorMessage($code, $args = array(), $state = ERROR_RAISE_TEXT)
    {
        if (!is_array($args)) {
            return 'Error: $args passed to Error_Util::genErrorMessage is '.
                'not an array but a '.gettype($args);
        }
        $messages =
        array(
            ERROR_UTIL_ERROR_CLASS_DOESNT_EXIST =>
                'class "%cl%" does not exist',
            ERROR_UTIL_ERROR_INVALID_INPUT =>
                'invalid input, parameter #%paramnum% '
                    . '"%var%" was expecting '
                    . '"%expected%", instead got "%was%"',
            ERROR_UTIL_ERROR_METHOD_DOESNT_EXIST =>
                'method "%method%" doesn\'t exist in class "%class%"',
            ERROR_UTIL_ERROR_FUNCTION_DOESNT_EXIST =>
                'function "%function%" doesn\'t exist',
            ERROR_UTIL_ERROR_INTERNAL_FUNCTION =>
                'function "%function%" is an internal function, and '
                    . 'cannot be used as a callback',
             );
        if (is_int($code) && isset($messages[$code])) {
            $msg = $messages[$code];
            return Error_Raise::sprintfErrorMessageWithState($msg,
                $args, $state);
        } else {
            return 'Error: code ' . $code . ' not found';
        }
    }
}
?>
Return current item: ZZ/OSS Installer