[ Index ]

PHP Cross Reference of MyBB

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


Generated: Tue Oct 8 19:19:50 2013 Cross-referenced by PHPXref 0.7.1