<?php
define('idDiGIR_errors','$Id: DiGIR_errors.php,v 1.7 2003/08/04 21:32:10 vieglais Exp $');
if (defined('idDIGIR_VERSION_REQUEST'))
    return;
/**
* $Id: DiGIR_errors.php,v 1.7 2003/08/04 21:32:10 vieglais Exp $
*
* Implements the Errors module for DiGIR provider
* Calling this file directly will generate a list of the defined error constants.
*/

/**
* Global variable that contains all the error (diagnostic) objects for a request
*/
$g_LastError = array();

//DiGIR_errorconst.php is generated by applying error_php.xslt against digir_errors.xml
require_once('DiGIR_errorconst.php');

/**
* Install error trap to capture unexpected problems
**/

define ('FATAL',E_USER_ERROR);
define ('ERROR',E_USER_WARNING);
define ('WARNING',E_USER_NOTICE);

// set the error reporting level for this script
error_reporting (FATAL | ERROR | WARNING);


/**
* Class Error
*
* Implements an error log for a DiGIR request
* An error is identified by a string constant with further information
* provided by an optional description element.
* Errors are really diagnostics with several levels of severity:
* debug, info, warn, error, fatal
*/
class Error
{
    var $m_code;
    var $m_description;
    var $m_severity;

    /*
    * Constructor for Error class
    * @param string $code
    * @param string $descr
    * @param string $severity
    */
    function Error($code="E_OK",$descr="",$severity="info")
    {
            $this->m_code = $code;
            $this->m_description = $descr;
            $this->m_severity = $severity;
    }

    /*
    * Generates a string representation of the error object
    */
    function toString()
    {
        return $this->m_severity."(".$this->m_code."):".$this->m_description;
    }

    /*
    * Generates an XML representation of the error code ala DiGIR
    */
    function toDiagnostic($clientKey="")
    {
        $s = "<diagnostic";
        if (strlen($clientKey) > 0)
        {
            $s .= " clientKey='".$clientKey."'";
        }
        $s .= " code=\"".$this->m_code."\" severity=\"".$this->m_severity."\">";
        $s .= escapeXMLSpecialChars($this->m_description);
        $s = $s."</diagnostic>\n";
        return $s;
    }
}

/**
* Adds a diagnostic to the end of the session's list of diagnostics
* @param cd = the diagnostic code
* @param msg = the message associated with the diagnostic
* @param severity = severity level for the diagnostic
*/
function AppendError($cd,$msg,$severity)
{
	global $g_LastError;
	array_push($g_LastError,new Error($cd,$msg,$severity));
}

/**
* Returns the number of diagnostics in the list
* @param severity = comma delimited list of level(s) to count.
*/
function ErrorCount($severity)
{
    global $g_LastError;
    $asev = explode(",",$severity);
    $ns = count($asev);
    $n = count($g_LastError);
    $ntot = 0;
    for ($i=0; $i<$n; $i++)
    {
        for ($j=0; $j < $ns; $j++)
        {
            if ($g_LastError[$i]->m_severity == $asev[$j])
                $ntot ++;
        }
    }
    return $ntot;
}

/**
* Returns the number of diagnostics in the list
* @param severity = array of error levels.
*/
function ErrorCountA($severity)
{
    global $g_LastError;
    $ntot = 0;
    foreach ($g_LastError as $k=>$v)
    {
        if (in_array($v->m_severity,$severity))
            $ntot ++;
    }
    return $ntot;
}


/**
* prints out the errors
*/
function DumpErrors()
{
    global $g_LastError;
    $n = count($g_LastError);
    echo "Errors [$n]";
    for ($i=0; $i<$n; $i++)
    {
        echo $g_LastError[$i]->toString()."\n";
    }
}

/**
* returns a string that is the complete <diagnostics> section of a DiGIR Response document.
*/
function DiGIRErrors($clientKey = "")
{
    global $g_LastError;
    $s = "<diagnostics>\n";
    for ($i=0; $i < count($g_LastError); $i++)
    {
        $err = $g_LastError[$i];
        $s .= $err->toDiagnostic($clientKey);
    }
    $s .= "</diagnostics>";
    return $s;
}

// error handler function
function DiGIRErrorHandler ($errno, $errstr, $errfile, $errline)
{
    switch ($errno)
    {
    case FATAL:
        /*
        * The error is causing termination of the script.  Try and bail
        * by pushing the existing diagnostics and terminating the xml stream.
        */
        appendError("PHP_Fatal_Error_[$errno]","$errstr ($errfile:$errline)",DIAG_FATAL);
        exit;
        break;
    case ERROR:
        appendError("PHP Error [$errno]","$errstr",DIAG_ERROR);
        break;
    case WARNING:
        appendError("PHP Warning [$errno]","$errstr",DIAG_WARNING);
        break;
    default:
        appendError("Unknown PHP Error [$errno]","$errstr ($errfile:$errline)",DIAG_WARNING);
        break;
    }
}

//This block of code is executed if not part of a DiGIR_Request
if ((isset($_SERVER['SCRIPT_NAME']) && preg_match("/.\/DiGIR_errors.php/i",$_SERVER['SCRIPT_NAME'])) ||
    (isset($_SERVER['argv'][0]) && strcasecmp($_SERVER['argv'][0],'DiGIR_errors.php') === 0))
{
    //Start the response
    header ("Content-type: text/xml");
    echo "<?xml version='1.0' encoding='utf-8' ?".">\n";
    echo "<errordefs>\n";
    //Return a lsit of error codes and error types.
    $defs = get_defined_constants();
    echo "<severityTypes>\n";
    foreach ($defs as $k=>$v)
    {
        if (strpos($k,'DIAG_') === 0)
        {
            echo "<severity>$v</severity>\n";
        }
    }
    echo "</severityTypes>\n";
    echo "<codes>\n";
    foreach ($defs as $k=>$v)
    {
        if (strpos($k,'DC_') === 0)
        {
            echo "<code>$v</code>\n";
        }
    }
    echo "</codes>\n";
    echo "</errordefs>";
}

?>
