[ Index ]

PHP Cross Reference of MyBB 1.6.5

title

Body

[close]

/inc/ -> class_error.php (source)

   1  <?php
   2  /**
   3   * MyBB 1.6
   4   * Copyright 2010 MyBB Group, All Rights Reserved
   5   *
   6   * Website: http://mybb.com
   7   * License: http://mybb.com/about/license
   8   *
   9   * $Id: class_error.php 5297 2010-12-28 22:01:14Z Tomm $
  10   */
  11   
  12  // Set to 1 if recieving a blank page (template failure).
  13  define("MANUAL_WARNINGS", 0);
  14   
  15  // Define Custom MyBB error handler constants with a value not used by php's error handler.
  16  define("MYBB_SQL", 20);
  17  define("MYBB_TEMPLATE", 30);
  18  define("MYBB_GENERAL", 40);
  19  define("MYBB_NOT_INSTALLED", 41);
  20  define("MYBB_NOT_UPGRADED", 42);
  21  define("MYBB_INSTALL_DIR_EXISTS", 43);
  22  define("MYBB_SQL_LOAD_ERROR", 44);
  23  define("MYBB_CACHE_NO_WRITE", 45);
  24  define("MYBB_CACHEHANDLER_LOAD_ERROR", 46);
  25  
  26  if(!defined("E_STRICT"))
  27  {
  28      // This constant has been defined since PHP 5.
  29      define("E_STRICT", 2048);
  30  }
  31  
  32  if(!defined("E_RECOVERABLE_ERROR"))
  33  {
  34      // This constant has been defined since PHP 5.2.
  35      define("E_RECOVERABLE_ERROR", 4096);
  36  }
  37  
  38  if(!defined("E_DEPRECATED"))
  39  {
  40      // This constant has been defined since PHP 5.3.
  41      define("E_DEPRECATED", 8192);
  42  }
  43  
  44  class errorHandler {
  45  
  46      /**
  47       * Array of all of the error types
  48       *
  49       * @var array
  50       */
  51      public $error_types = array( 
  52          E_ERROR              => 'Error',
  53          E_WARNING            => 'Warning',
  54          E_PARSE              => 'Parsing Error',
  55          E_NOTICE             => 'Notice',
  56          E_CORE_ERROR         => 'Core Error',
  57          E_CORE_WARNING       => 'Core Warning',
  58          E_COMPILE_ERROR      => 'Compile Error',
  59          E_COMPILE_WARNING    => 'Compile Warning',
  60          E_DEPRECATED         => 'Deprecated Warning',
  61          E_USER_ERROR         => 'User Error',
  62          E_USER_WARNING       => 'User Warning',
  63          E_USER_NOTICE        => 'User Notice',
  64          E_STRICT             => 'Runtime Notice',
  65          E_RECOVERABLE_ERROR  => 'Catchable Fatal Error',
  66          MYBB_SQL              => 'MyBB SQL Error', 
  67          MYBB_TEMPLATE         => 'MyBB Template Error',
  68          MYBB_GENERAL         => 'MyBB Error',
  69          MYBB_NOT_INSTALLED     => 'MyBB Error',
  70          MYBB_NOT_UPGRADED      => 'MyBB Error',
  71          MYBB_INSTALL_DIR_EXISTS => 'MyBB Error',
  72          MYBB_SQL_LOAD_ERROR  => 'MyBB Error',
  73          MYBB_CACHE_NO_WRITE  => 'MyBB Error',
  74          MYBB_CACHEHANDLER_LOAD_ERROR => 'MyBB Error',
  75      );
  76      
  77      /**
  78       * Array of MyBB error types
  79       *
  80       * @var array
  81       */
  82      public $mybb_error_types = array(
  83          MYBB_SQL,
  84          MYBB_TEMPLATE,
  85          MYBB_GENERAL,
  86          MYBB_NOT_INSTALLED,
  87          MYBB_NOT_UPGRADED,
  88          MYBB_INSTALL_DIR_EXISTS,
  89          MYBB_SQL_LOAD_ERROR,
  90          MYBB_CACHE_NO_WRITE,
  91          MYBB_CACHEHANDLER_LOAD_ERROR,
  92      );
  93      
  94      /**
  95       * Array of all of the error types to ignore
  96       *
  97       * @var array
  98       */
  99      public $ignore_types = array(
 100          E_DEPRECATED,
 101          E_NOTICE,
 102          E_USER_NOTICE,
 103          E_STRICT
 104      );
 105      
 106      /**
 107       * String of all the warnings collected
 108       *
 109       * @var string
 110       */
 111      public $warnings = "";
 112  
 113      /**
 114       * Is MyBB in an errornous state? (Have we received an error?)
 115       *
 116       * @var boolean
 117       */
 118      public $has_errors = false;
 119      
 120      /**
 121       * Initializes the error handler
 122       *
 123       */
 124  	function __construct()
 125      {
 126          // Lets set the error handler in here so we can just do $handler = new errorHandler() and be all set up.
 127          $error_types = E_ALL;
 128          foreach($this->ignore_types as $bit)
 129          {
 130              $error_types = $error_types & ~$bit;
 131          }
 132          set_error_handler(array(&$this, "error"), $error_types);
 133      }
 134       
 135      /**
 136       * Parses a error for processing.
 137       *
 138       * @param string The error type (i.e. E_ERROR, E_FATAL)
 139       * @param string The error message
 140       * @param string The error file
 141       * @param integer The error line
 142       * @return boolean True if parsing was a success, otherwise assume a error
 143       */            
 144  	function error($type, $message, $file=null, $line=0)
 145      {
 146          global $mybb;
 147  
 148          // Error reporting turned off (either globally or by @ before erroring statement)
 149          if(error_reporting() == 0)
 150          {
 151              return true;
 152          }
 153  
 154          if(in_array($type, $this->ignore_types))
 155          {
 156              return true;
 157          }
 158  
 159          $file = str_replace(MYBB_ROOT, "", $file);
 160  
 161          $this->has_errors = true;
 162          
 163          // For some reason in the installer this setting is set to "<"
 164          $accepted_error_types = array('both', 'error', 'warning', 'none');
 165          if(!in_array($mybb->settings['errortypemedium'], $accepted_error_types))
 166          {
 167              $mybb->settings['errortypemedium'] = "both";
 168          }
 169          
 170          if(defined("IN_TASK"))
 171          {
 172              global $task;
 173              
 174              require_once  MYBB_ROOT."inc/functions_task.php";
 175              
 176              if($file)
 177              {
 178                  $filestr = " - Line: $line - File: $file";
 179              }
 180              
 181              add_task_log($task, "{$this->error_types[$type]} - [$type] ".var_export($message, true)."{$filestr}");
 182          }
 183          
 184          // Saving error to log file.
 185          if($mybb->settings['errorlogmedium'] == "log" || $mybb->settings['errorlogmedium'] == "both")
 186          {
 187              $this->log_error($type, $message, $file, $line);
 188          }
 189  
 190          // Are we emailing the Admin a copy?
 191          if($mybb->settings['errorlogmedium'] == "mail" || $mybb->settings['errorlogmedium'] == "both")
 192          {
 193              $this->email_error($type, $message, $file, $line);
 194          }
 195          
 196          // SQL Error
 197          if($type == MYBB_SQL)
 198          {
 199              $this->output_error($type, $message, $file, $line);
 200          }
 201          else
 202          {
 203              // Do we have a PHP error?
 204              if(my_strpos(my_strtolower($this->error_types[$type]), 'warning') === false)
 205              {
 206                  $this->output_error($type, $message, $file, $line);
 207              }
 208              // PHP Error
 209              else
 210              {
 211                  if($mybb->settings['errortypemedium'] == "none" || $mybb->settings['errortypemedium'] == "error")
 212                  {
 213                      echo "<div class=\"php_warning\">MyBB Internal: One or more warnings occured. Please contact your administrator for assistance.</div>"; 
 214                  }
 215                  else
 216                  {
 217                      global $templates;
 218                      
 219                      $warning = "<strong>{$this->error_types[$type]}</strong> [$type] $message - Line: $line - File: $file PHP ".PHP_VERSION." (".PHP_OS.")<br />\n";
 220                      if(is_object($templates) && method_exists($templates, "get") && !defined("IN_ADMINCP"))
 221                      {
 222                          $this->warnings .= $warning;
 223                          $this->warnings .= $this->generate_backtrace();
 224                      }
 225                      else
 226                      {
 227                          echo "<div class=\"php_warning\">{$warning}".$this->generate_backtrace()."</div>";
 228                      }
 229                  }
 230              }
 231          }
 232          
 233          return true;
 234      }
 235      
 236      /**
 237       * Returns all the warnings
 238       *
 239       * @return string The warnings
 240       */
 241  	function show_warnings()
 242      {
 243          global $lang, $templates;
 244          
 245          if(empty($this->warnings))
 246          {
 247              return false;
 248          }
 249          
 250          // Incase a template fails and we're recieving a blank page.
 251          if(MANUAL_WARNINGS)
 252          {
 253              echo $this->warnings."<br />";
 254          }
 255  
 256          if(!$lang->warnings)
 257          {
 258              $lang->warnings = "The following warnings occured:";
 259          }
 260      
 261          if(defined("IN_ADMINCP"))
 262          {
 263              $warning = makeacpphpwarning($this->warnings);
 264          }
 265          else
 266          {
 267              $template_exists = false;
 268              
 269              if(!is_object($templates) || !method_exists($templates, 'get'))
 270              {
 271                  if(@file_exists(MYBB_ROOT."inc/class_templates.php"))
 272                  {
 273                      @require_once  MYBB_ROOT."inc/class_templates.php";
 274                      $templates = new templates;
 275                      $template_exists = true;
 276                  }
 277              }
 278              else
 279              {
 280                  $template_exists = true;
 281              }
 282              
 283              if($template_exists == true)
 284              {
 285                  eval("\$warning = \"".$templates->get("php_warnings")."\";");
 286              }
 287          }
 288      
 289          return $warning;
 290      }
 291      
 292      /**
 293       * Triggers a user created error 
 294       * Example: $error_handler->trigger("Some Warning", E_USER_ERROR);
 295       *
 296       * @param string Message
 297       * @param string Type
 298       */
 299  	function trigger($message="", $type=E_USER_ERROR)
 300      {
 301          global $lang;
 302  
 303          if(!$message)
 304          {
 305              $message = $lang->unknown_user_trigger;
 306          }
 307  
 308          if(in_array($type, $this->mybb_error_types))
 309          {
 310              $this->error($type, $message);
 311          }
 312          else
 313          {
 314              trigger_error($message, $type);        
 315          }
 316      }
 317  
 318      /**
 319       * Logs the error in the specified error log file.
 320       *
 321       * @param string Warning type
 322       * @param string Warning message
 323       * @param string Warning file
 324       * @param integer Warning line
 325       */
 326  	function log_error($type, $message, $file, $line)
 327      {
 328          global $mybb;
 329  
 330          if($type == MYBB_SQL)
 331          {
 332              $message = "SQL Error: {$message['error_no']} - {$message['error']}\nQuery: {$message['query']}";
 333          }
 334          $error_data = "<error>\n";
 335          $error_data .= "\t<dateline>".TIME_NOW."</dateline>\n";
 336          $error_data .= "\t<script>".$file."</script>\n";
 337          $error_data .= "\t<line>".$line."</line>\n";
 338          $error_data .= "\t<type>".$type."</type>\n";
 339          $error_data .= "\t<friendly_type>".$this->error_types[$type]."</friendly_type>\n";
 340          $error_data .= "\t<message>".$message."</message>\n";
 341          $error_data .= "</error>\n\n";
 342  
 343          if(trim($mybb->settings['errorloglocation']) != "")
 344          {
 345              @error_log($error_data, 3, $mybb->settings['errorloglocation']);
 346          }
 347          else
 348          {
 349              @error_log($error_data, 0);
 350          }
 351      }
 352  
 353      /**
 354       * Emails the error in the specified error log file.
 355       *
 356       * @param string Warning type
 357       * @param string Warning message
 358       * @param string Warning file
 359       * @param integer Warning line
 360       */
 361  	function email_error($type, $message, $file, $line)
 362      {
 363          global $mybb;
 364          
 365          if(!$mybb->settings['adminemail'])
 366          {
 367              return false;
 368          }
 369  
 370          if($type == MYBB_SQL) 
 371          {
 372              $message = "SQL Error: {$message['error_no']} - {$message['error']}\nQuery: {$message['query']}";
 373          }
 374          
 375          $message = "Your copy of MyBB running on {$mybb->settings['bbname']} ({$mybb->settings['bburl']}) has experienced an error. Details of the error include:\n---\nType: $type\nFile: $file (Line no. $line)\nMessage\n$message";
 376  
 377          @my_mail($mybb->settings['adminemail'], "MyBB error on {$mybb->settings['bbname']}", $message, $mybb->settings['adminemail']);
 378      }
 379  
 380  	function output_error($type, $message, $file, $line)
 381      {
 382          global $mybb, $parser;
 383  
 384          if(!$mybb->settings['bbname'])
 385          {
 386              $mybb->settings['bbname'] = "MyBB";
 387          }
 388  
 389          if($type == MYBB_SQL)
 390          {        
 391              $title = "MyBB SQL Error";
 392              $error_message = "<p>MyBB has experienced an internal SQL error and cannot continue.</p>";
 393              if($mybb->settings['errortypemedium'] == "both" || $mybb->settings['errortypemedium'] == "error" || defined("IN_INSTALL") || defined("IN_UPGRADE"))
 394              {
 395                  $error_message .= "<dl>\n";
 396                  $error_message .= "<dt>SQL Error:</dt>\n<dd>{$message['error_no']} - {$message['error']}</dd>\n";
 397                  if($message['query'] != "")
 398                  {
 399                      $error_message .= "<dt>Query:</dt>\n<dd>{$message['query']}</dd>\n";
 400                  }
 401                  $error_message .= "</dl>\n";
 402              }
 403          }
 404          else
 405          {
 406              $title = "MyBB Internal Error";
 407              $error_message = "<p>MyBB has experienced an internal error and cannot continue.</p>";
 408              if($mybb->settings['errortypemedium'] == "both" || $mybb->settings['errortypemedium'] == "error" || defined("IN_INSTALL") || defined("IN_UPGRADE"))
 409              {
 410                  $error_message .= "<dl>\n";
 411                  $error_message .= "<dt>Error Type:</dt>\n<dd>{$this->error_types[$type]} ($type)</dd>\n";
 412                  $error_message .= "<dt>Error Message:</dt>\n<dd>{$message}</dd>\n";
 413                  if(!empty($file))
 414                  {
 415                      $error_message .= "<dt>Location:</dt><dd>File: {$file}<br />Line: {$line}</dd>\n";
 416                      if(!@preg_match('#config\.php|settings\.php#', $file) && @file_exists($file))
 417                      {
 418                          $code_pre = @file($file);
 419      
 420                          $code = "";
 421      
 422                          if(isset($code_pre[$line-4]))
 423                          {
 424                              $code .= $line-3 . ". ".$code_pre[$line-4];
 425                          }
 426      
 427                          if(isset($code_pre[$line-3]))
 428                          {
 429                              $code .= $line-2 . ". ".$code_pre[$line-3];
 430                          }
 431      
 432                          if(isset($code_pre[$line-2]))
 433                          {
 434                              $code .= $line-1 . ". ".$code_pre[$line-2];
 435                          }
 436      
 437                          $code .= $line . ". ".$code_pre[$line-1]; // The actual line.
 438      
 439                          if(isset($code_pre[$line]))
 440                          {
 441                              $code .= $line+1 . ". ".$code_pre[$line];
 442                          }
 443      
 444                          if(isset($code_pre[$line+1]))
 445                          {
 446                              $code .= $line+2 . ". ".$code_pre[$line+1];
 447                          }
 448      
 449                          if(isset($code_pre[$line+2]))
 450                          {
 451                              $code .= $line+3 . ". ".$code_pre[$line+2];
 452                          }
 453      
 454                          unset($code_pre);
 455      
 456                          $parser_exists = false;
 457      
 458                          if(!is_object($parser) || !method_exists($parser, 'mycode_parse_php'))
 459                          {
 460                              if(@file_exists(MYBB_ROOT."inc/class_parser.php"))
 461                              {
 462                                  @require_once  MYBB_ROOT."inc/class_parser.php";
 463                                  $parser = new postParser;
 464                                  $parser_exists = true;
 465                              }
 466                          }
 467                          else
 468                          {
 469                              $parser_exists = true;
 470                          }
 471      
 472                          if($parser_exists)
 473                          {
 474                              $code = $parser->mycode_parse_php($code, true);
 475                          }
 476                          else
 477                          {
 478                              $code = @nl2br($code);
 479                          }
 480      
 481                          $error_message .= "<dt>Code:</dt><dd>{$code}</dd>\n";
 482                      }
 483                  }
 484                  $backtrace = $this->generate_backtrace();
 485                  if($backtrace && !in_array($type, $this->mybb_error_types))
 486                  {
 487                      $error_message .= "<dt>Backtrace:</dt><dd>{$backtrace}</dd>\n";
 488                  }
 489                  $error_message .= "</dl>\n";
 490              }
 491          }
 492  
 493          if(isset($lang->settings['charset']))
 494          {
 495              $charset = $lang->settings['charset'];
 496          }
 497          else
 498          {
 499              $charset = 'UTF-8';
 500          }
 501  
 502          if(!headers_sent() && !defined("IN_INSTALL") && !defined("IN_UPGRADE"))
 503          {
 504              @header('HTTP/1.1 503 Service Temporarily Unavailable');
 505              @header('Status: 503 Service Temporarily Unavailable');
 506              @header('Retry-After: 1800'); 
 507              @header("Content-type: text/html; charset={$charset}");
 508              $_SERVER['PHP_SELF'] = htmlspecialchars_uni($_SERVER['PHP_SELF']);
 509              
 510              echo <<<EOF
 511      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 512  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
 513  <head profile="http://gmpg.org/xfn/11">
 514      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 515      <title>{$mybb->settings['bbname']} - Internal Error</title>
 516      <style type="text/css">
 517          body { background: #efefef; color: #000; font-family: Verdana; font-size: 12px; text-align: center; line-height: 1.4; }
 518          a:link { color: #026CB1; text-decoration: none;    }
 519          a:visited {    color: #026CB1;    text-decoration: none; }
 520          a:hover, a:active {    color: #000; text-decoration: underline; }
 521          #container { width: 600px; padding: 20px; background: #fff;    border: 1px solid #e4e4e4; margin: 100px auto; text-align: left; }
 522          h1 { margin: 0; background: url({$_SERVER['PHP_SELF']}?action=mybb_logo) no-repeat;    height: 82px; width: 248px; }
 523          #content { border: 1px solid #B60101; background: #fff; }
 524          h2 { font-size: 12px; padding: 4px; background: #B60101; color: #fff; margin: 0; }
 525          .invisible { display: none; }
 526          #error { padding: 6px; }
 527          #footer { font-size: 11px; border-top: 1px solid #ccc; padding-top: 10px; }
 528          dt { font-weight: bold; }
 529      </style>
 530  </head>
 531  <body>
 532      <div id="container">
 533          <div id="logo">
 534              <h1><a href="http://mybb.com/" title="MyBulletinBoard"><span class="invisible">MyBB</span></a></h1>
 535          </div>
 536  
 537          <div id="content">
 538              <h2>{$title}</h2>
 539  
 540              <div id="error">
 541                  {$error_message}
 542                  <p id="footer">Please contact the <a href="http://mybb.com">MyBB Group</a> for support.</p>
 543              </div>
 544          </div>
 545      </div>
 546  </body>
 547  </html>
 548  EOF;
 549          }
 550          else
 551          {
 552              echo <<<EOF
 553      <style type="text/css">
 554          #mybb_error_content { border: 1px solid #B60101; background: #fff; }
 555          #mybb_error_content h2 { font-size: 12px; padding: 4px; background: #B60101; color: #fff; margin: 0; }
 556          #mybb_error_error { padding: 6px; }
 557          #mybb_error_footer { font-size: 11px; border-top: 1px solid #ccc; padding-top: 10px; }
 558          #mybb_error_content dt { font-weight: bold; }
 559      </style>
 560      <div id="mybb_error_content">
 561          <h2>{$title}</h2>
 562          <div id="mybb_error_error">
 563          {$error_message}
 564              <p id="mybb_error_footer">Please contact the <a href="http://mybb.com">MyBB Group</a> for support.</p>
 565          </div>
 566      </div>
 567  EOF;
 568          }
 569          exit(1);
 570      }
 571  
 572      /**
 573       * Generates a backtrace if the server supports it.
 574       *
 575       * @return string The generated backtrace
 576       */
 577  	function generate_backtrace()
 578      {
 579          if(function_exists("debug_backtrace"))
 580          {
 581              $trace = debug_backtrace();
 582              $backtrace = "<table style=\"width: 100%; margin: 10px 0; border: 1px solid #aaa; border-collapse: collapse; border-bottom: 0;\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n";
 583              $backtrace .= "<thead><tr>\n";
 584              $backtrace .= "<th style=\"border-bottom: 1px solid #aaa; background: #ccc; padding: 4px; text-align: left; font-size: 11px;\">File</th>\n";
 585              $backtrace .= "<th style=\"border-bottom: 1px solid #aaa; background: #ccc; padding: 4px; text-align: left; font-size: 11px;\">Line</th>\n";
 586              $backtrace .= "<th style=\"border-bottom: 1px solid #aaa; background: #ccc; padding: 4px; text-align: left; font-size: 11px;\">Function</th>\n";
 587              $backtrace .= "</tr></thead>\n<tbody>\n";
 588  
 589              // Strip off this function from trace
 590              array_shift($trace);
 591  
 592              foreach($trace as $call)
 593              {
 594                  if(!$call['file']) $call['file'] = "[PHP]";
 595                  if(!$call['line']) $call['line'] = "&nbsp;";
 596                  if($call['class']) $call['function'] = $call['class'].$call['type'].$call['function'];
 597                  $call['file'] = str_replace(MYBB_ROOT, "/", $call['file']);
 598                  $backtrace .= "<tr>\n";
 599                  $backtrace .= "<td style=\"font-size: 11px; padding: 4px; border-bottom: 1px solid #ccc;\">{$call['file']}</td>\n";
 600                  $backtrace .= "<td style=\"font-size: 11px; padding: 4px; border-bottom: 1px solid #ccc;\">{$call['line']}</td>\n";
 601                  $backtrace .= "<td style=\"font-size: 11px; padding: 4px; border-bottom: 1px solid #ccc;\">{$call['function']}</td>\n";
 602                  $backtrace .= "</tr>\n";
 603              }
 604              $backtrace .= "</tbody></table>\n";
 605          }
 606          return $backtrace;
 607      }
 608  }
 609  ?>


Generated: Sun Dec 11 14:16:27 2011 Cross-referenced by PHPXref 0.7.1