1<?php 2/** 3 * PSI_Error class 4 * 5 * PHP version 5 6 * 7 * @category PHP 8 * @package PSI_Error 9 * @author Michael Cramer <BigMichi1@users.sourceforge.net> 10 * @copyright 2009 phpSysInfo 11 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version 12 * @version SVN: $Id: class.Error.inc.php 569 2012-04-16 06:08:18Z namiltd $ 13 * @link http://phpsysinfo.sourceforge.net 14 */ 15 /** 16 * class for the error handling in phpsysinfo 17 * 18 * @category PHP 19 * @package PSI_Error 20 * @author Michael Cramer <BigMichi1@users.sourceforge.net> 21 * @copyright 2009 phpSysInfo 22 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version 23 * @version Release: 3.0 24 * @link http://phpsysinfo.sourceforge.net 25 */ 26class PSI_Error 27{ 28 /** 29 * holds the instance of this class 30 * 31 * @static 32 * @var PSI_Error 33 */ 34 private static $_instance; 35 36 /** 37 * holds the error messages 38 * 39 * @var array 40 */ 41 private $_arrErrorList = array(); 42 43 /** 44 * current number ob errors 45 * 46 * @var integer 47 */ 48 private $_errors = 0; 49 50 /** 51 * initalize some used vars 52 */ 53 private function __construct() 54 { 55 $this->_errors = 0; 56 $this->_arrErrorList = array(); 57 } 58 59 /** 60 * Singleton function 61 * 62 * @return PSI_Error instance of the class 63 */ 64 public static function singleton() 65 { 66 if (!isset(self::$_instance)) { 67 $c = __CLASS__; 68 self::$_instance = new $c; 69 } 70 71 return self::$_instance; 72 } 73 74 /** 75 * triggers an error when somebody tries to clone the object 76 * 77 * @return void 78 */ 79 public function __clone() 80 { 81 trigger_error("Can't be cloned", E_USER_ERROR); 82 } 83 84 /** 85 * adds an phpsysinfo error to the internal list 86 * 87 * @param string $strCommand Command, which cause the Error 88 * @param string $strMessage additional Message, to describe the Error 89 * 90 * @return void 91 */ 92 public function addError($strCommand, $strMessage) 93 { 94 $this->_addError($strCommand, $this->_trace($strMessage)); 95 } 96 97 /** 98 * adds an error to the internal list 99 * 100 * @param string $strCommand Command, which cause the Error 101 * @param string $strMessage message, that describe the Error 102 * 103 * @return void 104 */ 105 private function _addError($strCommand, $strMessage) 106 { 107 $index = count($this->_arrErrorList) + 1; 108 $this->_arrErrorList[$index]['command'] = $strCommand; 109 $this->_arrErrorList[$index]['message'] = $strMessage; 110 $this->_errors++; 111 } 112 113 /** 114 * add a config error to the internal list 115 * 116 * @param string $strCommand Command, which cause the Error 117 * @param string $strMessage additional Message, to describe the Error 118 * 119 * @return void 120 */ 121 public function addConfigError($strCommand, $strMessage) 122 { 123 $this->_addError($strCommand, "Wrong Value in phpsysinfo.ini for ".$strMessage); 124 } 125 126 /** 127 * add a php error to the internal list 128 * 129 * @param string $strCommand Command, which cause the Error 130 * @param string $strMessage additional Message, to describe the Error 131 * 132 * @return void 133 */ 134 public function addPhpError($strCommand, $strMessage) 135 { 136 $this->_addError($strCommand, "PHP throws a error\n".$strMessage); 137 } 138 139 /** 140 * adds a waraning to the internal list 141 * 142 * @param string $strMessage Warning message to display 143 * 144 * @return void 145 */ 146 public function addWarning($strMessage) 147 { 148 $index = count($this->_arrErrorList) + 1; 149 $this->_arrErrorList[$index]['command'] = "WARN"; 150 $this->_arrErrorList[$index]['message'] = $strMessage; 151 } 152 153 /** 154 * converts the internal error and warning list to a XML file 155 * 156 * @return void 157 */ 158 public function errorsAsXML() 159 { 160 $dom = new DOMDocument('1.0', 'UTF-8'); 161 $root = $dom->createElement("phpsysinfo"); 162 $dom->appendChild($root); 163 $xml = new SimpleXMLExtended(simplexml_import_dom($dom), 'UTF-8'); 164 $generation = $xml->addChild('Generation'); 165 $generation->addAttribute('version', PSI_VERSION_STRING); 166 $generation->addAttribute('timestamp', time()); 167 $xmlerr = $xml->addChild("Errors"); 168 foreach ($this->_arrErrorList as $arrLine) { 169// $error = $xmlerr->addCData('Error', $arrLine['message']); 170 $error = $xmlerr->addChild('Error'); 171 $error->addAttribute('Message', $arrLine['message']); 172 $error->addAttribute('Function', $arrLine['command']); 173 } 174 header("Cache-Control: no-cache, must-revalidate\n"); 175 header("Content-Type: text/xml\n\n"); 176 echo $xml->getSimpleXmlElement()->asXML(); 177 exit(); 178 } 179 /** 180 * add the errors to an existing xml document 181 * 182 * @param String $encoding encoding 183 * 184 * @return SimpleXmlElement 185 */ 186 public function errorsAddToXML($encoding) 187 { 188 $dom = new DOMDocument('1.0', 'UTF-8'); 189 $root = $dom->createElement("Errors"); 190 $dom->appendChild($root); 191 $xml = simplexml_import_dom($dom); 192 $xmlerr = new SimpleXMLExtended($xml, $encoding); 193 foreach ($this->_arrErrorList as $arrLine) { 194// $error = $xmlerr->addCData('Error', $arrLine['message']); 195 $error = $xmlerr->addChild('Error'); 196 $error->addAttribute('Message', $arrLine['message']); 197 $error->addAttribute('Function', $arrLine['command']); 198 } 199 200 return $xmlerr->getSimpleXmlElement(); 201 } 202 /** 203 * check if errors exists 204 * 205 * @return boolean true if are errors logged, false if not 206 */ 207 public function errorsExist() 208 { 209 if ($this->_errors > 0) { 210 return true; 211 } else { 212 return false; 213 } 214 } 215 /** 216 * generate a function backtrace for error diagnostic, function is genearally based on code submitted in the php reference page 217 * 218 * @param string $strMessage additional message to display 219 * 220 * @return string formatted string of the backtrace 221 */ 222 private function _trace($strMessage) 223 { 224 $arrTrace = array_reverse(debug_backtrace()); 225 $strFunc = ''; 226 $strBacktrace = htmlspecialchars($strMessage)."\n\n"; 227 foreach ($arrTrace as $val) { 228 // avoid the last line, which says the error is from the error class 229 if ($val == $arrTrace[count($arrTrace) - 1]) { 230 break; 231 } 232 if (isset($val['file'])) { 233 $strBacktrace .= str_replace(PSI_APP_ROOT, ".", $val['file']).' on line '.$val['line']; 234 } 235 if ($strFunc) { 236 $strBacktrace .= ' in function '.$strFunc; 237 } 238 if ($val['function'] == 'include' || $val['function'] == 'require' || $val['function'] == 'include_once' || $val['function'] == 'require_once') { 239 $strFunc = ''; 240 } else { 241 $strFunc = $val['function'].'('; 242 if (isset($val['args'][0])) { 243 $strFunc .= ' '; 244 $strComma = ''; 245 foreach ($val['args'] as $valArgs) { 246 $strFunc .= $strComma.$this->_printVar($valArgs); 247 $strComma = ', '; 248 } 249 $strFunc .= ' '; 250 } 251 $strFunc .= ')'; 252 } 253 $strBacktrace .= "\n"; 254 } 255 256 return $strBacktrace; 257 } 258 /** 259 * convert some special vars into better readable output 260 * 261 * @param mixed $var value, which should be formatted 262 * 263 * @return string formatted string 264 */ 265 private function _printVar($var) 266 { 267 if (is_string($var)) { 268 $search = array("\x00", "\x0a", "\x0d", "\x1a", "\x09"); 269 $replace = array('\0', '\n', '\r', '\Z', '\t'); 270 271 return ('"'.str_replace($search, $replace, $var).'"'); 272 } elseif (is_bool($var)) { 273 if ($var) { 274 return ('true'); 275 } else { 276 return ('false'); 277 } 278 } elseif (is_array($var)) { 279 $strResult = 'array( '; 280 $strComma = ''; 281 foreach ($var as $key=>$val) { 282 $strResult .= $strComma.$this->_printVar($key).' => '.$this->_printVar($val); 283 $strComma = ', '; 284 } 285 $strResult .= ' )'; 286 287 return ($strResult); 288 } 289 // anything else, just let php try to print it 290 return (var_export($var, true)); 291 } 292} 293