[ Index ]

PHP Cross Reference of Limb3

title

Body

[close]

/web_app/src/filter/ -> lmbErrorHandlingFilter.class.php (source)

   1  <?php
   2  /*

   3   * Limb PHP Framework

   4   *

   5   * @link http://limb-project.com

   6   * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)

   7   * @license    LGPL http://www.gnu.org/copyleft/lesser.html

   8   */
   9  lmb_require('limb/filter_chain/src/lmbInterceptingFilter.interface.php');
  10  lmb_require('limb/core/src/lmbErrorGuard.class.php');
  11  
  12  /**

  13   * class lmbErrorHandlingFilter.

  14   *

  15   * @package web_app

  16   * @version $Id: lmbErrorHandlingFilter.class.php 6019 2007-06-27 14:29:40Z serega $

  17   */
  18  class lmbErrorHandlingFilter implements lmbInterceptingFilter
  19  {
  20    const CONTEXT_RADIUS    = 3;
  21    const MODE_DEVEL        = 'devel';
  22    const MODE_PRODUCTION   = 'production';
  23  
  24    protected $toolkit;
  25    protected $error_page;
  26    protected $mode;
  27  
  28    function __construct($error500_page = '')
  29    {
  30      if(!$error500_page)
  31        $error500_page = dirname(__FILE__) . '/../../template/server_error.html';
  32  
  33      $this->error_page = $error500_page;
  34  
  35      if(!defined('LIMB_APP_MODE'))
  36        $this->mode = self :: MODE_DEVEL;
  37      else
  38        $this->mode = LIMB_APP_MODE;
  39    }
  40  
  41    function run($filter_chain)
  42    {
  43      $this->toolkit = lmbToolkit :: instance();
  44  
  45      lmbErrorGuard :: registerFatalErrorHandler($this, 'handleFatalError');
  46      lmbErrorGuard :: registerExceptionHandler($this, 'handleException');
  47  
  48      $filter_chain->next();
  49    }
  50  
  51    function handleFatalError($error)
  52    {
  53      $this->toolkit->getLog()->error($error['message']);
  54      $this->toolkit->getResponse()->reset();
  55  
  56      if($this->mode == self :: MODE_DEVEL)
  57        $this->_echoErrorBacktrace($error);
  58  
  59      if($this->mode == self :: MODE_PRODUCTION)
  60        $this->_echoErrorPage();
  61  
  62      exit(1);
  63    }
  64  
  65    function handleException($e)
  66    {
  67      if(function_exists('debugBreak'))
  68        debugBreak();
  69  
  70      $this->toolkit->getLog()->exception($e);
  71      $this->toolkit->getResponse()->reset();
  72  
  73      if($this->mode == self :: MODE_DEVEL)
  74        $this->_echoExceptionBacktrace($e);
  75  
  76      if($this->mode == self :: MODE_PRODUCTION)
  77        $this->_echoErrorPage();
  78  
  79      exit(1);
  80    }
  81  
  82    function _echoErrorPage()
  83    {
  84      for($i=0; $i < ob_get_level(); $i++)
  85        ob_end_clean();
  86  
  87      echo file_get_contents($this->error_page);
  88    }
  89  
  90    protected function _echoErrorBacktrace($error)
  91    {
  92      $message = $error['message'];
  93      $trace = '';
  94      $file = $error['file'];
  95      $line = $error['line'];
  96      $context = htmlspecialchars($this->_getFileContext($file, $line));
  97      $request = htmlspecialchars($this->toolkit->getRequest()->dump());
  98  
  99      for($i=0; $i < ob_get_level(); $i++)
 100        ob_end_clean();
 101  
 102      $session = htmlspecialchars($this->toolkit->getSession()->dump());
 103      echo $this->_renderTemplate($message, $trace, $file, $line, $context, $request, $session);
 104    }
 105  
 106    protected function _echoExceptionBacktrace($e)
 107    {
 108      $error = htmlspecialchars($e->getMessage());
 109      $trace = htmlspecialchars($e->getTraceAsString());
 110      list($file, $line) = $this->_extractExceptionFileAndLine($e);
 111      $context = htmlspecialchars($this->_getFileContext($file, $line));
 112      $request = htmlspecialchars($this->toolkit->getRequest()->dump());
 113      $session = htmlspecialchars($this->toolkit->getSession()->dump());
 114  
 115      for($i=0; $i < ob_get_level(); $i++)
 116        ob_end_clean();
 117  
 118      echo $this->_renderTemplate($error, $trace, $file, $line, $context, $request, $session);
 119    }
 120  
 121    protected function _renderTemplate($error, $trace, $file, $line, $context, $request, $session)
 122    {
 123      $formatted_error = nl2br($error);
 124  
 125      $body = <<<EOD
 126  <html>
 127  <head>
 128    <title>{$error}</title>
 129    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 130    <style>
 131      body { background-color: #fff; color: #333; }
 132  
 133      body, p, ol, ul, td {
 134        font-family: verdana, arial, helvetica, sans-serif;
 135        font-size:   13px;
 136        line-height: 25px;
 137      }
 138  
 139      pre {
 140        background-color: #eee;
 141        padding: 10px;
 142        font-size: 11px;
 143        line-height: 18px;
 144      }
 145  
 146      a { color: #000; }
 147      a:visited { color: #666; }
 148      a:hover { color: #fff; background-color:#000; }
 149    </style>
 150  
 151    <script>
 152    function TextDump() {
 153      w = window.open('', "Error text dump", "scrollbars=yes,resizable=yes,status=yes,width=1000px,height=800px,top=100px,left=100px");
 154      w.document.write('<html><body>');
 155      w.document.write('<h1>' + document.getElementById('Title').innerHTML + '</h1>');
 156      w.document.write(document.getElementById('Context').innerHTML);
 157      w.document.write(document.getElementById('Trace').innerHTML);
 158      w.document.write(document.getElementById('Request').innerHTML);
 159      w.document.write(document.getElementById('Session').innerHTML);
 160      w.document.write('</body></html>');
 161      w.document.close();
 162    }
 163    </script>
 164  </head>
 165  <body>
 166  <h2 id='Title'>{$formatted_error}</h2>
 167  
 168  <a href="#" onclick="document.getElementById('Trace').style.display='none';document.getElementById('Context').style.display='block'; return false;">Context</a> |
 169  
 170  <a href="#" onclick="document.getElementById('Trace').style.display='block';document.getElementById('Context').style.display='none'; return false;">Call stack</a> |
 171  
 172  <a href="#" onclick="TextDump(); return false;">Raw dump</a>
 173  
 174  <div id="Context" style="display: block;">
 175  <h3>Error in '{$file}' around line {$line}:</h3>
 176  <pre>{$context}</pre>
 177  </div>
 178  
 179  <div id="Trace" style="display: none;">
 180  <h3>Call stack:</h3>
 181  <pre>{$trace}</pre>
 182  </div>
 183  
 184  <div id="Request">
 185  <h2>Request</h2>
 186  <pre>{$request}</pre>
 187  </div>
 188  
 189  <div id="Session">
 190  <h2>Session</h2>
 191  <pre>{$session}</pre>
 192  </div>
 193  
 194  </body>
 195  </html>
 196  EOD;
 197      return $body;
 198    }
 199  
 200    protected function _extractExceptionFileAndLine($e)
 201    {
 202      if($e instanceof WactException)
 203      {
 204        $params = $e->getParams();
 205        if(isset($params['file']))
 206          return array($params['file'], $params['line']);
 207      }
 208      return array($e->getFile(), $e->getLine());
 209    }
 210  
 211    protected function _getFileContext($file, $line_number)
 212    {
 213      $context = array();
 214      $i = 0;
 215      foreach(file($file) as $line)
 216      {
 217        $i++;
 218        if($i >= $line_number - self :: CONTEXT_RADIUS && $i <= $line_number + self :: CONTEXT_RADIUS)
 219          $context[] = $i . "\t" . $line;
 220  
 221        if($i > $line_number + self :: CONTEXT_RADIUS)
 222          break;
 223      }
 224  
 225      return "\n" . implode("", $context);
 226    }
 227  }
 228  
 229  ?>


Generated: Tue Oct 14 04:47:40 2008 Cross-referenced by PHPXref 0.7