Location: PHPKode > scripts > xError > xerror/class.xerror.php
<?
/**
* Generic error reporting and handling class.
*
* xError is a generic error reporting and handling class written in PHP. It may be used for development and/or monitoring purposes.
*
* @version 0.1
* @author Alexander Serbe <hide@address.com>
* @copyright Copyright © 2003 by Alexander Serbe. All rights reserved.
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*/

class xError
{
	/**
        * @var array $definitions Error definitions.
        * @access private
        */
        var $definitions;

        /**
        * @var array errorStack Error stack. Errors (non-fatal) that occurred during the execution of the script.
        * @access private
        */
        var $errorStack;

        /**
        * @var string $errorLog The error log file.
        * @access private
        */
        var $errorLog;

        /**
        * @var boolean $logFatalErrors Determine whether to log fatal errors or not.
        * @access private
        */
        var $logFatalErrors;

        /**
        * @var string $tmpFatal Template for fatal errors.
        * @access private
        */
        var $tmpFatal;

        /**
        * @var string $tmpNonFatal Template for non-fatal errors.
        * @access private
        */
        var $tmpNonFatal;

	/**
        * Initializes a new xError object.
        * @access public
        * @return void
        */
        function xError()
        {
		// Initialize object variables...
                $this->definitions = array();
                $this->errorStack = array();
                $this->errorLog = '';
                $this->tmpFatal = '';
                $this->tmpNonFatal = '';

                $this->logFatalErrors ( false );

                // Start output buffering
                ob_start();
        }

        /**
        * Checks if the passed error code exists in the list.
        * @access private
        * @return boolean
        * @param string $code The error code to be checked.
        */
        function checkErrorCode ( $code )
        {
                if ( count ( $this->errorDefinitions ) <= 0 )
                        return false;

                foreach ( $this->errorDefinitions as $error )
                {
                        if ( $error['code'] == $code )
                                return true;
                }

                return false;
        }

        /**
        * Displays a fatal error.
        * @access private
        * @return boolean
        * @param string $code Error code.
        */
        function displayFatalError ( $code )
        {
                // Check if error code exists
                if ( !$this->checkErrorCode ( $code ) )
                        return false;

                // Get the error definition
                $x = $this->getErrorDefinition ( $code );

                // Check if error is really 'fatal'
                if ( $x['type'] != 'fatal' )
                        return false;

                ob_clean();

                // Get exact time
                $yA = explode ( " ", microtime() );
                $ms = $yA[0];
                $time = $yA[1];
                $yB = date ( 'd M Y H:i:s', $time );
                $yC = $yB . substr ( $ms, 1, 7 );

                if ( $this->tmpFatal )
                {
                        $fp = fopen ( $this->tmpFatal, "r" );
                        $tmp = fread ( $fp, filesize ( $this->tmpFatal ) );
                        fclose ( $fp );

                        $errorMessage = "<b>$yC:</b> <i>" . $x['code'] . "</i> - " . $x['user'] . "<br /><br />" . $x['suggestions'];

                        $tmp = str_replace ( "<!-- error_messages -->", $errorMessage, $tmp );

                        echo $tmp;
                        exit;
                }

                return false;
        }

        /**
        * Displays non-fatal errors.
        * @access public
        * @return boolean
        */
        function displayNonFatalError()
        {
                ob_clean();

                if ( $this->tmpNonFatal )
                {
                        $fp = fopen ( $this->tmpNonFatal, "r" );
                        $tmp = fread ( $fp, filesize ( $this->tmpNonFatal ) );
                        fclose ( $fp );

                        $errorMsg = '<table border="0" cellpadding="3" cellspacing="0">';
                        $errorMsg .= '<tr>';
                        $errorMsg .= '<td valign="top"><b>Time</b></td>';
                        $errorMsg .= '<td valign="top"><b>Error Code</b></td>';
                        $errorMsg .= '<td valign="top"><b>Error /<br />Suggestions</b></td>';
                        $errorMsg .= '</tr>';
                        $errorMsg .= '<tr><td colspan="3"><hr noshade size="1" /></td></tr>';

                        for ( $i=0; $i<count ( $this->errorStack ); $i++ )
                        {
                                $cnt = $i + 1;
                                $error = $this->errorStack[$i];

                                $errorMsg .= '<tr>';
                                $errorMsg .= '<td valign="top">' . $error['time'] . '</td>';
                                $errorMsg .= '<td align="center" valign="top">' . $error['code'] . '</td>';
                                $errorMsg .= '<td valign="top">' . $error['user'];
                                if ( strlen ( $error['suggestions'] ) > 0 )
                                        $errorMsg .= '<br /><i>' . $error['suggestions'] . '</i>';
                                $errorMsg .= '</td>';
                                $errorMsg .= '</tr>';
                                $errorMsg .= '<tr><td colspan="3"><hr noshade size="1" /></td></tr>';
                        }

                        $tmp = str_replace ( "<!-- error_messages -->", $errorMsg, $tmp );

                        echo $tmp;
                        exit;
                }

                return false;
        }

        /**
        * Clears the error stack and returns its contents. Stops the output buffering.
        * @access public
        * @return array
        */
        function flushErrors()
        {
                // Store the contents of the error stack in a temporary array
                $x = $this->errorStack;

                // Empty error stack
                $this->errorStack = array();

                // Return error stack
                return $x;
        }

        /**
        * Returns an error from the error stack.
        * @access private
        * @return array
        * @param integer $element Element number.
        */
        function getError ( $element )
        {
                // Check if error stack has elements
                if ( count ( $this->errorStack ) <= 0 )
                        return false;

                if ( is_array ( $this->errorStack[$element] ) )
                        return $this->errorStack[$element];

                return false;
        }

        /**
        * Returns an error definition.
        * @access private
        * @return array
        * @param string $code The error code to be returned.
        */
        function getErrorDefinition ( $code )
        {
                // Check if code exists
                if ( !$this->checkErrorCode ( $code ) )
                        return false;

                foreach ( $this->errorDefinitions as $error )
                {
                        if ( $error['code'] == $code )
                                return $error;
                }

                return false;
        }

        /**
        * Imports error definitions from a text file.
        * @access public
        * @return boolean
        * @param string $file The text file, the error definitions reside in.
        */
        function importDefinitions ( $file )
        {
		// Check if passed file exists an is not empty
                if ( !file_exists ( $file ) || filesize ( $file ) <= 0 )
                	return false;

                // Initialize counters
                $cnt = 0;
                $lineCnt = 0;

                // Open file
                $fp = fopen ( $file, "r" );

                // Loop through file content and extract error definitions
                while ( !feof ( $fp ) )
                {
                	$lineCnt++;
			$line = fgets ( $fp );

                        $x = split ( ";", $line );

                        // Check if the error code exists already in the error list
                       	$y = $this->setError ( $x[0], $x[1], $x[2], $x[3], $x[4] );
                        ( $y ) ? $cnt++ : $cnt = $cnt;
                }

                // Close file
                fclose ( $fp );

                return ( $cnt != $lineCnt ) ? false : true;
        }

        /**
        * Determine whether fatal errors should be logged or not. (Log file has to be specified manually using the setLogFile method!)
        * @access public
        * @return boolean
        * @param boolean $flag True = log fatal errors; false = do not log fatal errors.
        */
        function logFatalErrors ( $flag )
        {
                if ( !is_bool ( $flag ) )
                        return false;

                $this->logFatalErrors = $flag;
                return true;
        }

        /**
        * Adds an error to the error stack.
        * @access public
        * @return boolean
        * @param string $code Error code.
        * @param string $addInfo Additional information on the error (e.g. SQL errors etc.)
        */
        function raiseError ( $code, $addInfo='' )
        {
                // Check error code
                if ( !$this->checkErrorCode ( $code ) )
                        return false;

                // Get exact time
                $x = explode ( " ", microtime() );
                $ms = $x[0];
                $time = $x[1];
                $y = date ( 'd M Y H:i:s', $time );
                $z = $y . substr ( $ms, 1, 7 );

                $error = $this->getErrorDefinition ( $code );

                if ( $error['type'] == 'fatal' )
                {
                        if ( $this->logFatalErrors && $this->errorLog )
                        {
                                $fp = fopen ( $this->errorLog, "a" );
                                $errorString = "$z;" . $error['code'] . ";" . $error['admin'] . ";" . $error['type'] . ";$addInfo\n";
                                fputs ( $fp, $errorString );
                                fclose ( $fp );
                        }

                        $this->displayFatalError ( $code );
                        return true;
                }

                $newError = array (
                        'time' => $z,
                        'code' => $error['code'],
                        'user' => $error['user'],
                        'admin' => $error['admin'],
                        'type' => $error['type'],
                        'suggestions' => $error['suggestions'],
                        'info' => $addInfo
                );

                $this->errorStack[] = $newError;

                return true;
        }

        /**
        * Adds an error definition to the list.
        * @access public
        * @return boolean
        * @param string $code Error code.
        * @param string $userMessage The error message for the "normal" user.
        * @param string $adminMessage The error message for administrators and/or developers.
        * @param string $type The error type (fatal, non-fatal)
        * @param string $suggestions Suggestions how to avoid the error.
        */
        function setError ( $code, $userMessage, $adminMessage='', $type='fatal', $suggestions='' )
        {
        	// Check if error code exists already in error list.
                if ( $this->checkErrorCode ( $code ) )
                	return false;

		// Check if error type is either 'fatal' or 'non-fatal'
                if ( $type != 'fatal' && $type != 'non-fatal' )
                	return false;

                $this->errorDefinitions[] = array (
                	'code' => $code,
                        'user' => $userMessage,
                        'admin' => $adminMessage,
                        'type' => $type,
                        'suggestions' => $suggestions
                );

                return true;
        }

        /**
        * Sets the error log.
        * @access public
        * @return void
        * @param string $file Log file.
        */
        function setLogFile ( $file )
        {
                $this->errorLog = $file;
        }

        /**
        * Sets the templates for the output of errors.
        * @access public
        * @return boolean
        * @param string $fatal Template for fatal errors
        * @param string $nonFatal Template for non-fatal errors
        */
        function setTemplates ( $fatal, $nonFatal='' )
        {
                $check = false;

                if ( strlen ( $fatal ) > 0 && file_exists ( $fatal ) )
                {
                        $check = true;
                        $this->tmpFatal = $fatal;
                }
                if ( strlen ( $nonFatal ) > 0 && file_exists ( $nonFatal ) )
                {
                        $check = false;
                        $this->tmpNonFatal = $nonFatal;
                }

                return $check;
        }

        /**
        * Writes the contents of the error stack into a log file.
        * @access public
        * @return boolean
        */
        function writeLog()
        {
                // Check if any errors were recorded
                if ( count ( $this->errorStack ) <= 0 )
                	return false;

                $fp = fopen ( $this->errorLog, "a" );

                for ( $i=0; $i<count ( $this->errorStack ); $i++ )
                {
                	$x = $this->getError ( $i );

                        $logString = $x['time'] . ";" . $x['code'] . ";" . $x['admin'] . ";" . $x['type'] . ";" . $x['info'] . "\n";

                        fputs ( $fp, $logString );
                }

                fclose ( $fp );
        }
}
?>
Return current item: xError