1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
|
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds class PMA_Error_Handler
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
require_once './libraries/Error.class.php';
/**
* handling errors
*
* @package PhpMyAdmin
*/
class PMA_Error_Handler
{
/**
* holds errors to be displayed or reported later ...
*
* @var array of PMA_Error
*/
protected $errors = array();
/**
* Constructor - set PHP error handler
*
*/
public function __construct()
{
/**
* Do not set ourselves as error handler in case of testsuite.
*
* This behavior is not tested there and breaks other tests as they
* rely on PHPUnit doing it's own error handling which we break here.
*/
if (!defined('TESTSUITE')) {
set_error_handler(array($this, 'handleError'));
}
}
/**
* Destructor
*
* stores errors in session
*
*/
public function __destruct()
{
if (isset($_SESSION)) {
if (! isset($_SESSION['errors'])) {
$_SESSION['errors'] = array();
}
// remember only not displayed errors
foreach ($this->errors as $key => $error) {
/**
* We don't want to store all errors here as it would
* explode user session.
*/
if (count($_SESSION['errors']) >= 10) {
$error = new PMA_Error(
0,
__('Too many error messages, some are not displayed.'),
__FILE__,
__LINE__
);
$_SESSION['errors'][$error->getHash()] = $error;
break;
} else if (($error instanceof PMA_Error)
&& ! $error->isDisplayed()
) {
$_SESSION['errors'][$key] = $error;
}
}
}
}
/**
* returns array with all errors
*
* @return array PMA_Error_Handler::$_errors
*/
protected function getErrors()
{
$this->checkSavedErrors();
return $this->errors;
}
/**
* Error handler - called when errors are triggered/occurred
*
* This calls the addError() function, escaping the error string
*
* @param integer $errno error number
* @param string $errstr error string
* @param string $errfile error file
* @param integer $errline error line
*
* @return void
*/
public function handleError($errno, $errstr, $errfile, $errline)
{
$this->addError($errstr, $errno, $errfile, $errline, true);
}
/**
* Add an error; can also be called directly (with or without escaping)
*
* The following error types cannot be handled with a user defined function:
* E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR,
* E_COMPILE_WARNING,
* and most of E_STRICT raised in the file where set_error_handler() is called.
*
* Do not use the context parameter as we want to avoid storing the
* complete $GLOBALS inside $_SESSION['errors']
*
* @param string $errstr error string
* @param integer $errno error number
* @param string $errfile error file
* @param integer $errline error line
* @param boolean $escape whether to escape the error string
*
* @return void
*/
public function addError($errstr, $errno, $errfile, $errline, $escape = true)
{
if ($escape) {
$errstr = htmlspecialchars($errstr);
}
// create error object
$error = new PMA_Error(
$errno,
$errstr,
$errfile,
$errline
);
// do not repeat errors
$this->errors[$error->getHash()] = $error;
switch ($error->getNumber()) {
case E_USER_NOTICE:
case E_USER_WARNING:
case E_STRICT:
case E_DEPRECATED:
case E_NOTICE:
case E_WARNING:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
// just collect the error
// display is called from outside
break;
case E_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
default:
// FATAL error, display it and exit
$this->dispFatalError($error);
exit;
break;
}
}
/**
* log error to configured log facility
*
* @param PMA_Error $error the error
*
* @return bool
*
* @todo finish!
*/
protected function logError($error)
{
return error_log($error->getMessage());
}
/**
* trigger a custom error
*
* @param string $errorInfo error message
* @param integer $errorNumber error number
* @param string $file file name
* @param integer $line line number
*
* @return void
*/
public function triggerError($errorInfo, $errorNumber = null,
$file = null, $line = null
) {
// we could also extract file and line from backtrace
// and call handleError() directly
trigger_error($errorInfo, $errorNumber);
}
/**
* display fatal error and exit
*
* @param PMA_Error $error the error
*
* @return void
*/
protected function dispFatalError($error)
{
if (! headers_sent()) {
$this->dispPageStart($error);
}
$error->display();
$this->dispPageEnd();
exit;
}
/**
* Displays user errors not displayed
*
* @return void
*/
public function dispUserErrors()
{
echo $this->getDispUserErrors();
}
/**
* Renders user errors not displayed
*
* @return string
*/
public function getDispUserErrors()
{
$retval = '';
foreach ($this->getErrors() as $error) {
if ($error->isUserError() && ! $error->isDisplayed()) {
$retval .= $error->getDisplay();
}
}
return $retval;
}
/**
* display HTML header
*
* @param PMA_error $error the error
*
* @return void
*/
protected function dispPageStart($error = null)
{
PMA_Response::getInstance()->disable();
echo '<html><head><title>';
if ($error) {
echo $error->getTitle();
} else {
echo 'phpMyAdmin error reporting page';
}
echo '</title></head>';
}
/**
* display HTML footer
*
* @return void
*/
protected function dispPageEnd()
{
echo '</body></html>';
}
/**
* renders errors not displayed
*
* @return string
*/
public function getDispErrors()
{
$retval = '';
if ($GLOBALS['cfg']['Error_Handler']['display']) {
foreach ($this->getErrors() as $error) {
if ($error instanceof PMA_Error) {
if (! $error->isDisplayed()) {
$retval .= $error->getDisplay();
}
} else {
ob_start();
var_dump($error);
$retval .= ob_get_contents();
ob_end_clean();
}
}
} else {
$retval .= $this->getDispUserErrors();
}
return $retval;
}
/**
* displays errors not displayed
*
* @return void
*/
public function dispErrors()
{
echo $this->getDispErrors();
}
/**
* look in session for saved errors
*
* @return void
*/
protected function checkSavedErrors()
{
if (isset($_SESSION['errors'])) {
// restore saved errors
foreach ($_SESSION['errors'] as $hash => $error) {
if ($error instanceof PMA_Error && ! isset($this->errors[$hash])) {
$this->errors[$hash] = $error;
}
}
//$this->errors = array_merge($_SESSION['errors'], $this->errors);
// delete stored errors
$_SESSION['errors'] = array();
unset($_SESSION['errors']);
}
}
/**
* return count of errors
*
* @return integer number of errors occoured
*/
public function countErrors()
{
return count($this->getErrors());
}
/**
* return count of user errors
*
* @return integer number of user errors occoured
*/
public function countUserErrors()
{
$count = 0;
if ($this->countErrors()) {
foreach ($this->getErrors() as $error) {
if ($error->isUserError()) {
$count++;
}
}
}
return $count;
}
/**
* whether use errors occurred or not
*
* @return boolean
*/
public function hasUserErrors()
{
return (bool) $this->countUserErrors();
}
/**
* whether errors occurred or not
*
* @return boolean
*/
public function hasErrors()
{
return (bool) $this->countErrors();
}
/**
* number of errors to be displayed
*
* @return integer number of errors to be displayed
*/
public function countDisplayErrors()
{
if ($GLOBALS['cfg']['Error_Handler']['display']) {
return $this->countErrors();
} else {
return $this->countUserErrors();
}
}
/**
* whether there are errors to display or not
*
* @return boolean
*/
public function hasDisplayErrors()
{
return (bool) $this->countDisplayErrors();
}
}
?>
|