Skip to content

Commit cbe40e3

Browse files
committed
init commit
1 parent 1fd2635 commit cbe40e3

File tree

6 files changed

+698
-0
lines changed

6 files changed

+698
-0
lines changed

ErrorHandler/.DS_Store

6 KB
Binary file not shown.

ErrorHandler/ErrorHandler.php

Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Force Components.
5+
*
6+
* (c) Romanenko Sergey / Awilum <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
class ErrorHandler
13+
{
14+
15+
/**
16+
* Error Levels
17+
*/
18+
public static $levels = array (
19+
E_ERROR => 'Fatal Error',
20+
E_PARSE => 'Parse Error',
21+
E_COMPILE_ERROR => 'Compile Error',
22+
E_COMPILE_WARNING => 'Compile Warning',
23+
E_STRICT => 'Strict Mode Error',
24+
E_NOTICE => 'Notice',
25+
E_WARNING => 'Warning',
26+
E_RECOVERABLE_ERROR => 'Recoverable Error',
27+
E_USER_NOTICE => 'Notice',
28+
E_USER_WARNING => 'Warning',
29+
E_USER_ERROR => 'Error',
30+
);
31+
32+
/**
33+
* Protected constructor since this is a static class.
34+
*
35+
* @access protected
36+
*/
37+
protected function __construct()
38+
{
39+
// Nothing here
40+
}
41+
42+
/**
43+
* Returns an array of lines from a file.
44+
*
45+
* @access public
46+
* @param string $file File in which you want to highlight a line
47+
* @param int $line Line number to highlight
48+
* @param int $padding (optional) Number of padding lines
49+
* @return array
50+
*/
51+
protected static function highlightCode($file, $line, $padding = 6)
52+
{
53+
if ( ! is_readable($file)) {
54+
return false;
55+
}
56+
57+
$handle = fopen($file, 'r');
58+
$lines = array();
59+
$currentLine = 0;
60+
61+
while ( ! feof($handle)) {
62+
$currentLine++;
63+
64+
$temp = fgets($handle);
65+
66+
if ($currentLine > $line + $padding) {
67+
break; // Exit loop after we have found what we were looking for
68+
}
69+
70+
if ($currentLine >= ($line - $padding) && $currentLine <= ($line + $padding)) {
71+
$lines[] = array
72+
(
73+
'number' => str_pad($currentLine, 4, ' ', STR_PAD_LEFT),
74+
'highlighted' => ($currentLine === $line),
75+
'code' => ErrorHandler::highlightString($temp),
76+
);
77+
}
78+
}
79+
80+
fclose($handle);
81+
82+
return $lines;
83+
}
84+
85+
/**
86+
* Converts errors to ErrorExceptions.
87+
*
88+
* @param integer $code The error code
89+
* @param string $message The error message
90+
* @param string $file The filename where the error occurred
91+
* @param integer $line The line number where the error occurred
92+
* @return boolean
93+
*/
94+
public static function error($code, $message, $file, $line)
95+
{
96+
// If isset error_reporting and $code then throw new error exception
97+
if ((error_reporting() & $code) !== 0) {
98+
99+
/**
100+
* Dont thow NOTICE exception for PRODUCTION Environment. Just write to log.
101+
*/
102+
if (DEVELOPMENT == false && $code == 8) {
103+
104+
// Get exception info
105+
$error['code'] = $code;
106+
$error['message'] = $message;
107+
$error['file'] = $file;
108+
$error['line'] = $line;
109+
$error['type'] = 'ErrorException: ';
110+
111+
$codes = array (
112+
E_USER_NOTICE => 'Notice',
113+
);
114+
115+
$error['type'] .= in_array($error['code'], array_keys($codes)) ? $codes[$error['code']] : 'Unknown Error';
116+
117+
// Write to log
118+
ErrorHandler::writeLogs("{$error['type']}: {$error['message']} in {$error['file']} at line {$error['line']}");
119+
120+
} else {
121+
throw new ErrorException($message, $code, 0, $file, $line);
122+
}
123+
}
124+
125+
// Don't execute PHP internal error handler
126+
return true;
127+
}
128+
129+
/**
130+
* Highlight string
131+
*
132+
* @param string $string String
133+
* @return string
134+
*/
135+
protected static function highlightString($string)
136+
{
137+
$search = array("\r\n", "\n\r", "\r", "\n", '<code>', '</code>', '<span style="color: #0000BB">&lt;?php&nbsp;', '#$@r4!/*');
138+
$replace = array('', '', '', '', '', '', '<span style="color: #0000BB">', '/*');
139+
140+
return str_replace($search, $replace, highlight_string('<?php ' . str_replace('/*', '#$@r4!/*', $string), true));
141+
}
142+
143+
/**
144+
* Modifies the backtrace array.
145+
*
146+
* @access protected
147+
* @param array $backtrace Array returned by the getTrace() method of an exception object
148+
* @return array
149+
*/
150+
protected static function formatBacktrace($backtrace)
151+
{
152+
if (is_array($backtrace) === false || count($backtrace) === 0) {
153+
return $backtrace;
154+
}
155+
156+
/**
157+
* Remove unnecessary info from backtrace
158+
*/
159+
if ($backtrace[0]['function'] == '{closure}') {
160+
unset($backtrace[0]);
161+
}
162+
163+
/**
164+
* Format backtrace
165+
*/
166+
$trace = array();
167+
168+
foreach ($backtrace as $entry) {
169+
170+
/**
171+
* Function
172+
*/
173+
$function = '';
174+
175+
if (isset($entry['class'])) {
176+
$function .= $entry['class'] . $entry['type'];
177+
}
178+
179+
$function .= $entry['function'] . '()';
180+
181+
/**
182+
* Arguments
183+
*/
184+
$arguments = array();
185+
186+
if (isset($entry['args']) && count($entry['args']) > 0) {
187+
foreach ($entry['args'] as $arg) {
188+
ob_start();
189+
190+
var_dump($arg);
191+
192+
$arg = htmlspecialchars(ob_get_contents());
193+
194+
ob_end_clean();
195+
196+
$arguments[] = $arg;
197+
}
198+
}
199+
200+
/**
201+
* Location
202+
*/
203+
$location = array();
204+
205+
if (isset($entry['file'])) {
206+
$location['file'] = $entry['file'];
207+
$location['line'] = $entry['line'];
208+
$location['code'] = self::highlightCode($entry['file'], $entry['line']);
209+
}
210+
211+
/**
212+
* Compile into array
213+
*/
214+
$trace[] = array
215+
(
216+
'function' => $function,
217+
'arguments' => $arguments,
218+
'location' => $location,
219+
);
220+
}
221+
222+
return $trace;
223+
}
224+
225+
/**
226+
* Convert errors not caught by the error handler to ErrorExceptions.
227+
*/
228+
public static function fatal()
229+
{
230+
$e = error_get_last();
231+
232+
if ($e !== null && (error_reporting() & $e['type']) !== 0) {
233+
ErrorHandler::exception(new ErrorException($e['message'], $e['type'], 0, $e['file'], $e['line']));
234+
235+
exit(1);
236+
}
237+
}
238+
239+
/**
240+
* Writes message to log.
241+
*
242+
* @access public
243+
* @param string $message The message to write to the log
244+
* @return boolean
245+
*/
246+
public static function writeLogs($message)
247+
{
248+
return (bool) file_put_contents(rtrim(LOGS_PATH, '/') . '/' . gmdate('Y_m_d') . '.log',
249+
'[' . gmdate('d-M-Y H:i:s') . '] ' . $message . PHP_EOL,
250+
FILE_APPEND);
251+
}
252+
253+
/**
254+
* Handles uncaught exceptions and returns a pretty error screen.
255+
*
256+
* @access public
257+
* @param Exception $exception An exception object
258+
*/
259+
public static function exception($exception)
260+
{
261+
try {
262+
263+
// Empty output buffers
264+
while(ob_get_level() > 0) ob_end_clean();
265+
266+
// Get exception info
267+
$error['code'] = $exception->getCode();
268+
$error['message'] = $exception->getMessage();
269+
$error['file'] = $exception->getFile();
270+
$error['line'] = $exception->getLine();
271+
272+
// Determine error type
273+
if ($exception instanceof ErrorException) {
274+
$error['type'] = 'ErrorException: ';
275+
$error['type'] .= in_array($error['code'], array_keys(ErrorHandler::$levels)) ? ErrorHandler::$levels[$error['code']] : 'Unknown Error';
276+
} else {
277+
$error['type'] = get_class($exception);
278+
}
279+
280+
// Write to log
281+
ErrorHandler::writeLogs("{$error['type']}: {$error['message']} in {$error['file']} at line {$error['line']}");
282+
283+
// Send headers and output
284+
@header('Content-Type: text/html; charset=UTF-8');
285+
286+
if (DEVELOPMENT) {
287+
288+
$error['backtrace'] = $exception->getTrace();
289+
290+
if ($exception instanceof ErrorException) {
291+
$error['backtrace'] = array_slice($error['backtrace'], 1); //Remove call to error handler from backtrace
292+
}
293+
294+
$error['backtrace'] = self::formatBacktrace($error['backtrace']);
295+
$error['highlighted'] = self::highlightCode($error['file'], $error['line']);
296+
297+
@header('HTTP/1.1 500 Internal Server Error');
298+
include 'Resources/Views/Errors/exception.php';
299+
300+
} else {
301+
302+
@header('HTTP/1.1 500 Internal Server Error');
303+
include 'Resources/Views/Errors/production.php';
304+
305+
}
306+
307+
} catch (Exception $e) {
308+
309+
// Empty output buffers
310+
while(ob_get_level() > 0) ob_end_clean();
311+
312+
echo $e->getMessage() . ' in ' . $e->getFile() . ' (line ' . $e->getLine() . ').';
313+
}
314+
315+
exit(1);
316+
}
317+
}

ErrorHandler/Resources/.DS_Store

6 KB
Binary file not shown.

0 commit comments

Comments
 (0)