Complex classes like Errorhandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Errorhandler, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
42 | class Errorhandler |
||
43 | { |
||
44 | /** |
||
45 | * Registers this class as the new PHP errorhandler, thereby overwriting any previous handlers. |
||
46 | */ |
||
47 | public static function register() |
||
54 | |||
55 | /** |
||
56 | * Handle Error as ErrorException. |
||
57 | * |
||
58 | * @param int $errnum contains the error as integer. |
||
59 | * @param string $message contains the error string. |
||
60 | * @param string $filename contains the filename with occuring error. |
||
61 | * @param int $lineno contains the line of error. |
||
62 | * |
||
63 | * @throws \ErrorException |
||
64 | */ |
||
65 | public function handleErrorAsErrorException($errnum, $message, $filename, $lineno) |
||
69 | |||
70 | /** |
||
71 | * Koch Framework - Error callback. |
||
72 | * |
||
73 | * This is basically a switch statement, defining the actions taken, |
||
74 | * in case of serveral PHP error states. |
||
75 | * |
||
76 | * @link http://www.usegroup.de/software/phptutorial/debugging.html |
||
77 | * @link http://www.php.net/manual/de/function.set-error-handler.php |
||
78 | * @link http://www.php.net/manual/de/errorfunc.constants.php |
||
79 | * |
||
80 | * @param int $errnum contains the error as integer. |
||
81 | * @param string $errstr contains the error string. |
||
82 | * @param string $errfile contains the filename with occuring error. |
||
83 | * @param string $errline contains the line of error. |
||
84 | * @param string $errcontext (optional) array with variables from error context. |
||
85 | */ |
||
86 | public static function handleError($errnum, $errstr, $errfile, $errline, $errcontext = null) |
||
87 | { |
||
88 | // return, if the error is suppressed, due to (@)silencing-operator |
||
89 | if (error_reporting() === 0) { |
||
90 | return; |
||
91 | } |
||
92 | |||
93 | /* |
||
94 | * Assemble the error informations |
||
95 | */ |
||
96 | |||
97 | /* |
||
98 | * Definition of PHP error types, with names for all the php error codes. |
||
99 | * @link http://php.net/manual/de/errorfunc.constants.php |
||
100 | */ |
||
101 | $errorTypes = [ |
||
102 | 1 => 'E_ERROR', // fatal run-time errors, like php is failing memory allocation |
||
103 | 2 => 'E_WARNING', // Run-time warnings (non-fatal errors) |
||
104 | 4 => 'E_PARSE', // compile-time parse errors - generated by the parser |
||
105 | 8 => 'E_NOTICE', // Run-time notices (could be an indicator for an error) |
||
106 | 16 => 'E_CORE_ERROR', // PHP Core reports errors in PHP's initial startup |
||
107 | 32 => 'E_CORE_WARNING', // PHP Core reports warning (non-fatal errors) |
||
108 | 64 => 'E_COMPILE_ERROR', // Zend Script Engine reports fatal compile-time errors |
||
109 | 128 => 'E_COMPILE_WARNING', // Zend Script Engine reports compile-time warnings (non-fatal errors) |
||
110 | 256 => 'E_USER_ERROR', // trigger_error(), user_error() reports user-defined error |
||
111 | 512 => 'E_USER_WARNING', // trigger_error(), user_error() reports user-defined warning |
||
112 | 1024 => 'E_USER_NOTICE', // trigger_error(), user_error() reports user-defined notice |
||
113 | 2048 => 'E_STRICT', // PHP suggests codechanges to ensure interoperability / forwad compat |
||
114 | 4096 => 'E_RECOVERABLE_ERROR', // catchable fatal error, if not catched it's an e_error (since PHP 5.2.0) |
||
115 | 8191 => 'E_ALL 8191', // PHP 6 -> 8191 |
||
116 | 8192 => 'E_DEPRECATED', // notice marker for 'in future' deprecated php-functions (since PHP 5.3.0) |
||
117 | 16384 => 'E_USER_DEPRECATED', // trigger_error(), user_error() reports user-defined deprecated functions |
||
118 | 30719 => 'E_ALL 30719 PHP5.3.x', // all errors and warnings - E_ALL of PHP Version 5.3.x |
||
119 | 32767 => 'E_ALL 32767 PHP6', // all errors and warnings - E_ALL of PHP Version 6 |
||
120 | ]; |
||
121 | |||
122 | // get the errorname from the array via $errornumber |
||
123 | $errorname = isset($errorTypes[$errnum]) ? $errorTypes[$errnum] : ''; |
||
124 | |||
125 | // Handling the ErrorType via Switch |
||
126 | switch ($errorname) { |
||
127 | // This one is handled by register_shutdown_function + catchFatalErrorsShutdownHandler |
||
128 | case 'E_ERROR': |
||
129 | $errorname .= ' [PHP Fatal Error]'; |
||
130 | break; |
||
131 | // What are the errortypes that can be handled by a user-defined errorhandler? |
||
132 | case 'E_WARNING': |
||
133 | $errorname .= ' [PHP Warning]'; |
||
134 | break; |
||
135 | case 'E_NOTICE': |
||
136 | $errorname .= ' [PHP Notice]'; |
||
137 | break; |
||
138 | case 'E_USER_ERROR': |
||
139 | $errorname .= ' [Koch Framework Internal Error]'; |
||
140 | break; |
||
141 | case 'E_USER_WARNING': |
||
142 | $errorname .= ' [Koch Framework Internal Error]'; |
||
143 | break; |
||
144 | case 'E_USER_NOTICE': |
||
145 | $errorname .= ' [Koch Framework Internal Error]'; |
||
146 | break; |
||
147 | case 'E_ALL': |
||
148 | case 'E_STRICT': |
||
149 | $errorname .= ' [PHP Strict]'; |
||
150 | break; |
||
151 | case 'E_RECOVERABLE_ERROR': |
||
152 | $errorname .= ' [php not-unstable]'; |
||
153 | break; |
||
154 | // when it's not in there, its an unknown errorcode |
||
155 | default: |
||
156 | $errorname .= ' Unknown Errorcode [' . $errnum . ']: '; |
||
157 | } |
||
158 | |||
159 | // make the errorstring more useful by linking it to the php manual |
||
160 | $pattern = "/<a href='(.*)'>(.*)<\/a>/"; |
||
161 | $replacement = '<a href="http://php.net/$1" target="_blank">?</a>'; |
||
162 | $errstr = preg_replace($pattern, $replacement, $errstr); |
||
163 | |||
164 | // if DEBUG is set, display the error |
||
165 | if (defined('DEBUG') and DEBUG === 1) { |
||
166 | |||
167 | /* |
||
168 | * SMARTY ERRORS are thrown by trigger_error() - so they bubble up as E_USER_ERROR. |
||
169 | * |
||
170 | * In order to handle smarty errors with an seperated error display, |
||
171 | * we need to detect, if an E_USER_ERROR is either incoming from |
||
172 | * SMARTY or from a template_c file (extension tpl.php). |
||
173 | */ |
||
174 | if ((true === (bool) mb_strpos(mb_strtolower($errfile), 'smarty')) or |
||
175 | (true === (bool) mb_strpos(mb_strtolower($errfile), 'tpl.php'))) { |
||
176 | // render the smarty template error |
||
177 | echo SmartyTemplateError::render($errnum, $errorname, $errstr, $errfile, $errline, $errcontext); |
||
178 | } else { |
||
179 | // render normal error display, with all pieces of information, except backtraces |
||
180 | echo YellowScreenOfDeath::renderError($errnum, $errorname, $errstr, $errfile, $errline, $errcontext); |
||
181 | } |
||
182 | } |
||
183 | |||
184 | // Skip PHP internal error handler |
||
185 | return true; |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * getTemplateEditorLink. |
||
190 | * |
||
191 | * a) determines the path to the invalid template file |
||
192 | * b) provides the html-link to the templateeditor for this file |
||
193 | * |
||
194 | * @param string $errfile Template File with the Error. |
||
195 | * @param string $errline Line Number of the Error. |
||
196 | * @param string|null $errcontext |
||
197 | * |
||
198 | * @todo correct link to the templateeditor |
||
199 | */ |
||
200 | public static function getTemplateEditorLink($errfile, $errline, $errcontext) |
||
201 | { |
||
202 | // display the link to the templateeditor, if we are in DEVELOPMENT MODE |
||
203 | // and more essential if the error relates to a template file |
||
204 | if (defined('DEVELOPMENT') and DEVELOPMENT === 1 && (mb_strpos(mb_strtolower($errfile), '.tpl'))) { |
||
205 | // ok, it's a template, so we have a template context to determine the templatename |
||
206 | $tpl_vars = $errcontext['this']->getTemplateVars(); |
||
207 | |||
208 | // maybe the templatename is defined in tpl_vars |
||
209 | if ($tpl_vars['templatename'] !== null) { |
||
210 | $errfile = $tpl_vars['templatename']; |
||
211 | } else { // else use resource_name from the errorcontext |
||
212 | $errfile = $errcontext['resource_name']; |
||
213 | } |
||
214 | |||
215 | // construct the link to the tpl-editor |
||
216 | $html = '<br/><a href="index.php?mod=templatemanager&sub=admin&action=editor'; |
||
217 | $html .= '&file=' . $errfile . '&line=' . $errline; |
||
218 | $html .= '">Edit the Template</a>'; |
||
219 | |||
220 | // return the link |
||
221 | return $html; |
||
222 | } |
||
223 | } |
||
224 | |||
225 | /** |
||
226 | * getDebugBacktrace. |
||
227 | * |
||
228 | * Transforms the output of php's debug_backtrace() and exception backtraces |
||
229 | * to a more readable html format. |
||
230 | * |
||
231 | * @return string $backtrace_string contains the backtrace |
||
232 | */ |
||
233 | public static function getDebugBacktrace($trace = null) |
||
234 | { |
||
235 | // show backtraces only in DEBUG mode |
||
236 | if (defined('DEBUG') === false xor DEBUG === 0) { |
||
237 | return; |
||
238 | } |
||
239 | |||
240 | // Normally backtraces are incomming from exceptions. |
||
241 | // But, when called from the errorhandler, we need to fetch the traces ourselfs. |
||
242 | if ($trace === null) { |
||
243 | if (function_exists('xdebug_get_function_stack')) { |
||
244 | $trace = xdebug_get_function_stack(); |
||
245 | } else { |
||
246 | $trace = debug_backtrace(); |
||
247 | } |
||
248 | |||
249 | /* |
||
250 | * Now we get rid of several last calls in the backtrace stack, |
||
251 | * to get nearer to the relevant error position in the stack. |
||
252 | * |
||
253 | * What exactly happens is: we shift-off the last 3 calls to |
||
254 | * 1) getDebugBacktrace() [this method itself] |
||
255 | * 2) yellowScreenOfDeath() [our exception and error display method] |
||
256 | * 3) trigger_error() [php core function call] |
||
257 | */ |
||
258 | $trace = array_slice($trace, 3); |
||
259 | } |
||
260 | |||
261 | /* |
||
262 | * Assemble the html for the backtrace panel |
||
263 | */ |
||
264 | $html = ''; |
||
265 | $html .= '<div id="panel3" class="panel"><h3>Backtrace</h3>'; |
||
266 | $html .= '<table class="cs-backtrace-table" width="95%">'; |
||
267 | |||
268 | // table row 1 - header |
||
269 | $html .= '<tr><th width="2%">Callstack</th><th>Function</th><th width="46%">Location</th></tr>'; |
||
270 | |||
271 | // the number of backtraces |
||
272 | $backtraces_counter_i = count($trace) - 1; |
||
273 | |||
274 | for ($i = 0; $i <= $backtraces_counter_i; ++$i) { |
||
275 | $html .= '<tr>'; |
||
276 | |||
277 | // Position in the Callstack |
||
278 | $html .= '<td align="center">' . (($backtraces_counter_i - $i) + 1) . '</td>'; |
||
279 | |||
280 | if (isset($trace[$i]['class']) === false) { |
||
281 | $html .= '<td>[A PHP Core Function Call]</td>'; |
||
282 | } else { |
||
283 | |||
284 | // replace trace type string with it's operator |
||
285 | if ($trace[$i]['type'] === 'dynamic') { |
||
286 | $trace[$i]['type'] = '->'; |
||
287 | } else { |
||
288 | $trace[$i]['type'] = '::'; |
||
289 | } |
||
290 | |||
291 | $html .= '<td>'; |
||
292 | |||
293 | // show the function call, e.g. Class->Method() or Class::Method() |
||
294 | $html .= $trace[$i]['class'] . $trace[$i]['type'] . $trace[$i]['function'] . '()'; |
||
295 | |||
296 | // if the class is one of our own, add backlink to API Documentation |
||
297 | if (1 === preg_match('/^Koch/', $trace[$i]['class'])) { |
||
298 | $html .= '<span class="error-class">'; |
||
299 | $html .= '<a target="_new" href="http://docs.kf.com/en/latest/api/'; |
||
300 | $html .= str_replace('\\', '_', $trace[$i]['class']); |
||
301 | $html .= '.html"> ' . $trace[$i]['class'] . '</a></span>'; |
||
302 | } else { |
||
303 | // else it's a php internal class, then add a backlink to the php manual |
||
304 | $classReflection = new \ReflectionClass($trace[$i]['class']); |
||
305 | if ($classReflection->isInternal()) { |
||
306 | $html .= '<span class="error-class"><a target="_new" href="http://php.net/manual/en/class.'; |
||
307 | $html .= str_replace('_', '-', strtolower($trace[$i]['class'])); |
||
308 | $html .= '.php">' . $trace[$i]['class'] . '</a></span>'; |
||
309 | } else { |
||
310 | $html .= '<span class="error-class">' . $trace[$i]['class'] . '</span>'; |
||
311 | } |
||
312 | } |
||
313 | |||
314 | // is this a normal php function? if yes, add a backlink to the php manual |
||
315 | if (function_exists($trace[$i]['function'])) { |
||
316 | $functionReflection = new \ReflectionFunction($trace[$i]['function']); |
||
317 | if ($functionReflection->isInternal()) { |
||
318 | $html .= '<span class="error-function">'; |
||
319 | $html .= '<a target="_new" href="http://php.net/manual/en/function.'; |
||
320 | $html .= str_replace('_', '-', $trace[$i]['function']); |
||
321 | $html .= '.php">' . $trace[$i]['function'] . '</a></span>'; |
||
322 | } |
||
323 | } |
||
324 | |||
325 | // XDebug uses the array key 'params' for the method parameters array |
||
326 | // PHP backtrace uses 'args', so let's rename to 'args' |
||
327 | if (isset($trace[$i]['params'])) { |
||
328 | $trace[$i]['args'] = $trace[$i]['params']; |
||
329 | unset($trace[$i]['params']); |
||
330 | } |
||
331 | |||
332 | // Method Arguments |
||
333 | if (isset($trace[$i]['args']) && empty($trace[$i]['args']) === false) { |
||
334 | // the number of arguments (method parameters) |
||
335 | $backtrace_counter_j = count($trace[$i]['args']) - 1; |
||
336 | |||
337 | // use reflection to get the method parameters (and their names for display) |
||
338 | $reflected_method = new \ReflectionMethod($trace[$i]['class'], $trace[$i]['function']); |
||
339 | /* @var $reflected_params \ReflectionParameter */ |
||
340 | $reflected_params = $reflected_method->getParameters(); |
||
341 | |||
342 | // render a table with method parameters |
||
343 | // argument position | name | type | value |
||
344 | $html .= '<table style="border-collapse: collapse;">'; |
||
345 | $html .= '<tr><th style="line-height: 0.8em;" colspan="4">Parameters</th></tr>'; |
||
346 | $html .= '<tr style="line-height: 0.8em;">'; |
||
347 | $html .= '<th>Pos</th><th>Name = Default Value</th><th>Type</th><th>Value</th></tr>'; |
||
348 | |||
349 | // loop over all arguments |
||
350 | for ($j = 0; $j <= $backtrace_counter_j; ++$j) { |
||
351 | // fetch data for this argument |
||
352 | $data = self::formatBacktraceArgument($trace[$i]['args'][$j]); |
||
353 | // fetch current reflection parameter object |
||
354 | $parameter = $reflected_params[$j]; |
||
355 | // get just the parameter name and it's default value |
||
356 | preg_match('/\[ ([^[]+) \]/', $parameter, $matches); |
||
357 | |||
358 | $html .= '<tr>'; |
||
359 | $html .= '<td>' . ($j + 1) . '</td>'; // pos |
||
360 | $html .= '<td>' . $matches['1'] . '</td>'; // name |
||
361 | $html .= '<td>' . $data['type'] . '</td>'; // type |
||
362 | $html .= '<td>' . $data['arg'] . '</td>'; // value $defaultValue |
||
363 | } |
||
364 | $html .= '</tr></table>'; |
||
365 | } |
||
366 | $html .= '</td>'; |
||
367 | } |
||
368 | |||
369 | // Location with Link |
||
370 | if (isset($trace[$i]['file'])) { |
||
371 | $html .= '<td>' . self::getFileLink($trace[$i]['file'], $trace[$i]['line']) . '</td>'; |
||
372 | } |
||
373 | |||
374 | $html .= '</tr>'; |
||
375 | } |
||
376 | |||
377 | $html .= '</table></div>'; |
||
378 | |||
379 | return $html; |
||
380 | } |
||
381 | |||
382 | /** |
||
383 | * formatBacktraceArgument. |
||
384 | * |
||
385 | * Performs a type check on the backtrace argument and beautifies it. |
||
386 | * |
||
387 | * This formater is based on comments for debug-backtrace in the php manual |
||
388 | * |
||
389 | * @link http://de2.php.net/manual/en/function.debug-backtrace.php#30296 |
||
390 | * @link http://de2.php.net/manual/en/function.debug-backtrace.php#47644 |
||
391 | * |
||
392 | * @param backtraceArgument mixed The argument for type identification and string formatting. |
||
393 | * |
||
394 | * @return array With keys 'arg' and 'type'. |
||
395 | */ |
||
396 | public static function formatBacktraceArgument($argument) |
||
397 | { |
||
398 | // do not throw a notice on PHP 5.3 - the constant was added with PHP 5.4 htmlspecialchars() |
||
399 | defined('ENT_SUBSTITUTE') || define('ENT_SUBSTITUTE', 8); |
||
400 | |||
401 | $result = []; |
||
402 | $arg = ''; |
||
403 | $type = ''; |
||
404 | |||
405 | switch (gettype($argument)) { |
||
406 | case 'boolean': |
||
407 | $type .= '<span>bool</span>'; |
||
408 | $arg .= $argument ? 'true' : 'false'; |
||
409 | break; |
||
410 | case 'integer': |
||
411 | $type .= '<span>int</span>'; |
||
412 | $arg .= $argument; |
||
413 | break; |
||
414 | case 'float': |
||
415 | case 'double': |
||
416 | $type .= '<span>float/double</span>'; |
||
417 | $arg .= $argument; |
||
418 | break; |
||
419 | case 'string': |
||
420 | $type .= '<span>string</span>'; |
||
421 | $argument = htmlspecialchars($argument, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); |
||
422 | $arg .= \Koch\Functions\Functions::shortenString($argument); |
||
423 | break; |
||
424 | case 'array': |
||
425 | $type .= '<span>array</span>'; |
||
426 | $arg .= count($argument); |
||
427 | break; |
||
428 | case 'object': |
||
429 | $type .= '<span>object</span>'; |
||
430 | $arg .= get_class($argument); |
||
431 | /* @todo use self::getClassProperties($backtraceArgument) */ |
||
432 | break; |
||
433 | case 'resource': |
||
434 | $type .= '<span>resource</span>'; |
||
435 | if ($type === 'stream') { |
||
436 | $type .= '(stream)'; |
||
437 | $meta = stream_get_meta_data($argument); |
||
438 | if (isset($meta['uri'])) { |
||
439 | $type .= htmlspecialchars($meta['uri'], ENT_NOQUOTES, 'UTF-8'); |
||
440 | } |
||
441 | } |
||
442 | $arg .= mb_strstr($argument, '#') . ' - ' . get_resource_type($argument); |
||
443 | break; |
||
444 | case 'NULL': |
||
445 | $type .= '<span>null</span>'; |
||
446 | $arg .= ''; |
||
447 | break; |
||
448 | default: |
||
449 | $type .= 'Unknown'; |
||
450 | $arg .= 'Unknown'; |
||
451 | } |
||
452 | |||
453 | return compact('arg', 'type'); |
||
454 | } |
||
455 | |||
456 | public static function getClassProperties($class, $nestingLevel = 2) |
||
483 | |||
484 | /** |
||
485 | * getErrorContext displayes some additional lines of sourcecode around the line with error. |
||
486 | * |
||
487 | * @param string $file file with the error in it |
||
488 | * @param int $scope the context scope (defining how many lines surrounding the error are displayed) |
||
489 | * @param int $line the line with the error in it |
||
490 | * |
||
491 | * @return string sourcecode of file |
||
492 | */ |
||
493 | public static function getErrorContext($file, $line, $scope) |
||
494 | { |
||
495 | // ensure that sourcefile is readable |
||
496 | if (true === is_readable($file)) { |
||
497 | // Scope Calculations |
||
498 | $surround_lines = round($scope / 2); |
||
499 | $errorcontext_starting_line = $line - $surround_lines; |
||
500 | $errorcontext_ending_line = $line + $surround_lines; |
||
501 | |||
502 | // create linenumbers array |
||
503 | $lines_array = range($errorcontext_starting_line, $errorcontext_ending_line); |
||
504 | |||
505 | // colourize the errorous linenumber red |
||
506 | $lines_array[$surround_lines] = '<span class="error-line">' . $lines_array[$surround_lines] . '</span>'; |
||
507 | $lines_array[$surround_lines] .= '<span class="error-triangle">▶</span>'; |
||
508 | |||
509 | // transform linenumbers array to string for later display, use spaces as separator |
||
510 | $lines_html = implode($lines_array, ' '); |
||
511 | |||
512 | // get ALL LINES syntax highlighted source-code of the file and explode it into an array |
||
513 | // the if check is needed to workaround "highlight_file() has been disabled for security reasons" |
||
514 | if (function_exists('highlight_file')) { |
||
515 | $array_content = explode('<br />', highlight_file($file, true)); |
||
516 | } else { |
||
517 | $array_content = explode('<br />', $file); |
||
518 | } |
||
519 | |||
520 | // get the ERROR SURROUNDING LINES from ALL LINES |
||
521 | $array_content_sliced = array_slice($array_content, $errorcontext_starting_line - 1, $scope, true); |
||
522 | |||
523 | $result = array_values($array_content_sliced); |
||
524 | |||
525 | // @todo now colourize the background of the errorous line RED |
||
526 | //$result[$surround_lines] = '<span style="background-color:#BF0000;">' |
||
527 | // . $result[$surround_lines] .'</span>'; |
||
528 | |||
529 | // @todo remove 4 space identation, still buggy on inline stmts |
||
530 | //foreach ($result as $i => $line) { |
||
531 | // $result[$i] = str_replace(' ', '', $line); |
||
532 | //} |
||
533 | |||
534 | // transform the array into html string |
||
535 | // enhance readablility by imploding the array with spaces (try either ' ' or '<br>') |
||
536 | $errorcontext_lines = implode($result, '<br>'); |
||
537 | |||
538 | $sprintf_html = '<table> |
||
539 | <tr> |
||
540 | <td class="num">' . CR . '%s' . CR . '</td> |
||
541 | <td><pre>' . CR . '%s' . CR . '</pre></td> |
||
542 | </tr> |
||
543 | </table>'; |
||
544 | |||
545 | // @todo consider using wordwrap() to limit too long source code lines? |
||
546 | return sprintf($sprintf_html, $lines_html, $errorcontext_lines); |
||
547 | } |
||
548 | } |
||
549 | |||
550 | /** |
||
551 | * Returns the Clansuite Support Backlinks as HTML string. |
||
552 | * |
||
553 | * @return string Clansuite Support Backlinks as HTML. |
||
554 | */ |
||
555 | public static function getSupportBacklinks() |
||
556 | { |
||
557 | $html = '<div id="support-backlinks" style="padding-top: 45px; float:right;">'; |
||
558 | $html .= '<!-- Live Support JavaScript --> |
||
559 | <a class="btn" href="http://support.clansuite.com/chat.php"'; |
||
560 | $html .= ' target="_blank">Contact Support (Start Chat)</a> |
||
561 | <!-- Live Support JavaScript -->'; |
||
562 | $html .= '<a class="btn" href="http://trac.clansuite.com/newticket/">Bug-Report</a> |
||
563 | <a class="btn" href="http://forum.clansuite.com/">Support-Forum</a> |
||
564 | <a class="btn" href="http://docs.clansuite.com/">Manuals</a> |
||
565 | <a class="btn" href="http://clansuite.com/">visit clansuite.com</a> |
||
566 | <a class="btn" href="#top"> ▲ Top </a> |
||
567 | </div>'; |
||
568 | |||
569 | return $html; |
||
570 | } |
||
571 | |||
572 | /** |
||
573 | * Returns a link to the file:line with the error. |
||
574 | * |
||
575 | * a) This uses the file "xdebug.file_link_format" php.ini configuration directive, |
||
576 | * which defines a link template for calling your Editor/IDE with file and line. |
||
577 | * b) returns NO link, just file:line. |
||
578 | * |
||
579 | * @return string Link to file and line with error. |
||
580 | */ |
||
581 | public static function getFileLink($file, $line) |
||
582 | { |
||
583 | $file = str_replace(APPLICATION_PATH, '..' . DIRECTORY_SEPARATOR, $file); |
||
584 | |||
585 | // a |
||
586 | $fileLinkFormatString = ini_get('xdebug.file_link_format'); |
||
587 | if (isset($fileLinkFormatString)) { |
||
588 | $link = strtr($fileLinkFormatString, ['%f' => $file, '%l' => $line]); |
||
589 | |||
590 | return sprintf(' in <a href="%s" title="Edit file">%s line #%d</a>', $link, $file, $line); |
||
591 | } |
||
592 | |||
593 | // b |
||
594 | return sprintf(' in %s line #%d', $file, $line); |
||
595 | } |
||
596 | |||
597 | /** |
||
598 | * Adds a link to our bugtracker, for creating a new ticket with the errormessage. |
||
599 | * |
||
600 | * @param string $errorstring the errormessage |
||
601 | * |
||
602 | * @return string html-representation of the bugtracker links |
||
603 | */ |
||
604 | public static function getBugtrackerBacklinks($errorstring, $errorfile, $errorline, $errorcontext) |
||
605 | { |
||
606 | $msg1 = '<div id="panel5" class="panel"><h3>' . 'Found a bug in Clansuite?' . '</h3><p>'; |
||
607 | $msg2 = 'If you think this should work and you can reproduce the problem,'; |
||
608 | $msg2 .= ' please consider creating a bug report.'; |
||
609 | $msg3 = 'Before creating a new bug report, please first try searching for similar issues,'; |
||
610 | $msg3 .= ' as it is quite likely that this problem has been reported before.'; |
||
611 | $msg4 = 'Otherwise, please create a new bug report describing the problem and explain how to reproduce it.'; |
||
612 | |||
613 | $search_link = NL . NL . '<a class="btn" target="_blank" href="http://trac.clansuite.com/search?q='; |
||
614 | $search_link .= htmlentities($errorstring, ENT_QUOTES) . '&noquickjump=1&ticket=on">'; |
||
615 | $search_link .= '► Search for similar issue'; |
||
616 | $search_link .= '</a>'; |
||
617 | |||
618 | $newticket_link = ' <a class="btn" target="_blank" href="'; |
||
619 | $newticket_link .= self::getTracNewTicketURL($errorstring, $errorfile, $errorline) . '">'; |
||
620 | $newticket_link .= '► Create new ticket'; |
||
621 | $newticket_link .= '</a>'; |
||
622 | |||
623 | return $msg1 . $msg2 . NL . $msg3 . NL . $msg4 . $search_link . $newticket_link . '</p></div>' . NL; |
||
624 | } |
||
625 | |||
626 | /** |
||
627 | * Returns a link to Trac's New Ticket Dialog prefilled with error data. |
||
628 | * |
||
629 | * @returns string Link to Trac's Create New Ticket Dialog prefilled. |
||
630 | * |
||
631 | * @param string $summary |
||
632 | */ |
||
633 | public static function getTracNewTicketURL($summary, $errorfile, $errorline) |
||
634 | { |
||
635 | /* |
||
636 | * This is the error description. |
||
637 | * It's written in trac wiki formating style. |
||
638 | * |
||
639 | * @link http://trac.clansuite.com/wiki/WikiFormatting |
||
640 | */ |
||
641 | $description = '[Error] ' . $summary . ' [[BR]] [File] ' . $errorfile . ' [[BR]] [Line] ' . $errorline; |
||
642 | |||
643 | // options array for http_build_query |
||
644 | $array = [ |
||
645 | 'summary' => $summary, |
||
646 | 'description' => $description, |
||
647 | 'type' => 'defect-bug', |
||
648 | 'milestone' => 'Triage-Neuzuteilung', |
||
649 | 'version' => APPLICATION_VERSION, |
||
650 | #'component' => '', |
||
651 | 'author' => isset($_SESSION['user']['email']) ? $_SESSION['user']['email'] : '', |
||
652 | ]; |
||
653 | |||
654 | return 'http://trac.clansuite.com/newticket/?' . http_build_query($array); |
||
655 | } |
||
656 | |||
657 | /** |
||
658 | * Returns a link to a new Issue on Github. |
||
659 | * |
||
660 | * @link http://developer.github.com/v3/issues/#create-an-issue |
||
661 | */ |
||
662 | public static function getGithubIssueURL($summary, $errorfile, $errorline) |
||
678 | |||
679 | /** |
||
680 | * This method might be registered to the shutdown handler to catch fatal errors. |
||
681 | */ |
||
682 | public static function catchFatalErrors() |
||
683 | { |
||
684 | $lastError = error_get_last(); |
||
685 | |||
686 | // return early, if there hasn't been an error yet |
||
687 | if (null === $lastError) { |
||
705 | } |
||
706 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.