diff --git a/lib/SimpleSAML/XML/Errors.php b/lib/SimpleSAML/XML/Errors.php new file mode 100644 index 0000000000000000000000000000000000000000..9c4ccb7d1ed9a0f8f8b691e49871aefaf86ea7ac --- /dev/null +++ b/lib/SimpleSAML/XML/Errors.php @@ -0,0 +1,135 @@ +<?php + +/** + * This class defines an interface for accessing errors from the XML library. + * + * In PHP versions which doesn't support accessing error information, this class + * will hide that, and pretend that no errors were logged. + * + * @author Olav Morken, UNINETT AS. + * @package simpleSAMLphp + * @version $Id$ + */ +class SimpleSAML_XML_Errors { + + /** + * This is an stack of error logs. The topmost element is the one we are + * currently working on. + */ + private static $errorStack = array(); + + /** + * This is the xml error state we had before we began logging. + */ + private static $xmlErrorState; + + + /** + * Append current XML errors to the the current stack level. + */ + private static function addErrors() { + + $currentErrors = libxml_get_errors(); + libxml_clear_errors(); + + $level = count(self::$errorStack) - 1; + self::$errorStack[$level] = array_merge(self::$errorStack[$level], $currentErrors); + } + + + /** + * Start error logging. + * + * A call to this function will begin a new error logging context. Every call must have + * a corresponding call to end(). + */ + public static function begin() { + + /* Check whether the error access functions are present. */ + if(!function_exists('libxml_use_internal_errors')) { + return; + } + + if(count(self::$errorStack) === 0) { + /* No error logging is currently in progress. Initialize it. */ + self::$xmlErrorState = libxml_use_internal_errors(TRUE); + libxml_clear_errors(); + } else { + /* We have already started error logging. Append the current errors to the + * list of errors in this level. + */ + self::addErrors(); + } + + /* Add a new level to the error stack. */ + self::$errorStack[] = array(); + } + + + /** + * End error logging. + * + * @return An array with the LibXMLErrors which has occured since begin() was called. + */ + public static function end() { + + /* Check whether the error access functions are present. */ + if(!function_exists('libxml_use_internal_errors')) { + /* Pretend that no errors occured. */ + return array(); + } + + /* Add any errors which may have occured. */ + self::addErrors(); + + + $ret = array_pop(self::$errorStack); + + if(count(self::$errorStack) === 0) { + /* Disable our error logging and restore the previous state. */ + libxml_use_internal_errors(self::$xmlErrorState); + } + + return $ret; + } + + + /** + * Format an error as a string. + * + * This function formats the given LibXMLError object as a string. + * + * @param $error The LibXMLError which should be formatted. + * @return A string representing the given LibXMLError. + */ + public static function formatError($error) { + assert('$error instanceof LibXMLError'); + return 'level=' . $error->level . ',code=' . $error->code . ',line=' . $error->line . ',col=' . $error->column . + ',msg=' . trim($error->message); + } + + + /** + * Format a list of errors as a string. + * + * This fucntion takes an array of LibXMLError objects and creates a string with all the errors. + * Each error will be separated by a newline, and the string will end with a newline-character. + * + * @param $errors An array of errors. + * @return A string representing the errors. An empty string will be returned if there were no + * errors in the array. + */ + public static function formatErrors($errors) { + assert('is_array($errors)'); + + $ret = ''; + foreach($errors as $error) { + $ret .= self::formatError($error) . "\n"; + } + + return $ret; + } + +} + +?> \ No newline at end of file