| [ Index ] |
PHP Cross Reference of Limb3 |
[Summary view] [Print] [Text view]
1 <?php 2 /* 3 * Limb PHP Framework 4 * 5 * @link http://limb-project.com 6 * @copyright Copyright © 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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Tue Oct 14 04:47:40 2008 | Cross-referenced by PHPXref 0.7 |