Completed
Branch newinternal (113bb8)
by Michael
05:12
created

ExceptionHandler::exceptionHandler()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 65
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 31
c 1
b 0
f 0
dl 0
loc 65
ccs 0
cts 48
cp 0
rs 9.424
cc 4
nc 8
nop 1
crap 20

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca;
10
11
use ErrorException;
12
use Exception;
13
14
class ExceptionHandler
15
{
16
    /**
17
     * Global exception handler
18
     *
19
     * Smarty would be nice to use, but it COULD BE smarty that throws the errors.
20
     * Let's build something ourselves, and hope it works.
21
     *
22
     * @param $exception
23
     *
24
     * @category Security-Critical - has the potential to leak data when exception is thrown.
25
     */
26
    public static function exceptionHandler(Exception $exception)
0 ignored issues
show
Coding Style Best Practice introduced by
Please use __construct() instead of a PHP4-style constructor that is named after the class.
Loading history...
27
    {
28
        /** @global $siteConfiguration SiteConfiguration */
29
        global $siteConfiguration;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
30
31
        $errorDocument = <<<HTML
32
<!DOCTYPE html>
33
<html lang="en"><head>
34
<meta charset="utf-8">
35
<title>Oops! Something went wrong!</title>
36
<meta name="viewport" content="width=device-width, initial-scale=1.0">
37
<link href="{$siteConfiguration->getBaseUrl()}/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet">
38
<style>
39
  body {
40
    padding-top: 60px;
41
  }
42
</style>
43
<link href="{$siteConfiguration->getBaseUrl()}/lib/bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet">
44
</head><body><div class="container">
45
<h1>Oops! Something went wrong!</h1>
46
<p>We'll work on fixing this for you, so why not come back later?</p>
47
<p class="muted">If our trained monkeys ask, tell them this error ID: <code>$1$</code></p>
48
$2$
49
</div></body></html>
50
HTML;
51
52
        $errorData = self::getExceptionData($exception);
53
        $errorData['server'] = $_SERVER;
54
        $errorData['get'] = $_GET;
55
        $errorData['post'] = $_POST;
56
57
        $state = serialize($errorData);
58
        $errorId = sha1($state);
59
60
        // Save the error for later analysis
61
        file_put_contents($siteConfiguration->getErrorLog() . '/' . $errorId . '.log', $state);
62
63
        // clear and discard any content that's been saved to the output buffer
64
        if (ob_get_level() > 0) {
65
            ob_end_clean();
66
        }
67
68
        // push error ID into the document.
69
        $message = str_replace('$1$', $errorId, $errorDocument);
70
71
        if ($siteConfiguration->getDebuggingTraceEnabled()) {
72
            ob_start();
73
            var_dump($errorData);
1 ignored issue
show
Security Debugging Code introduced by
var_dump($errorData) looks like debug code. Are you sure you do not want to remove it?
Loading history...
74
            $textErrorData = ob_get_contents();
75
            ob_end_clean();
76
77
            $message = str_replace('$2$', $textErrorData, $message);
78
        }
79
        else {
80
            $message = str_replace('$2$', "", $message);
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
81
        }
82
83
        // While we *shouldn't* have sent headers by now due to the output buffering, PHPUnit does weird things.
84
        // This is "only" needed for the tests, but it's a good idea to wrap this anyway.
85
        if (!headers_sent()) {
86
            header('HTTP/1.1 500 Internal Server Error');
87
        }
88
89
        // output the document
90
        print $message;
91
    }
0 ignored issues
show
Coding Style introduced by
Expected //end exceptionHandler()
Loading history...
92
93
    /**
94
     * @param int    $errorSeverity The severity level of the exception.
95
     * @param string $errorMessage  The Exception message to throw.
96
     * @param string $errorFile     The filename where the exception is thrown.
97
     * @param int    $errorLine     The line number where the exception is thrown.
98
     *
99
     * @throws ErrorException
100
     */
101
    public static function errorHandler($errorSeverity, $errorMessage, $errorFile, $errorLine)
102
    {
103
        // call into the main exception handler above
104
        throw new ErrorException($errorMessage, 0, $errorSeverity, $errorFile, $errorLine);
105
    }
0 ignored issues
show
Coding Style introduced by
Expected //end errorHandler()
Loading history...
106
107
    /**
108
     * @param Exception $exception
109
     *
110
     * @return null|array
111
     */
112
    private static function getExceptionData($exception)
113
    {
114
        if ($exception == null) {
115
            return null;
116
        }
117
118
        return array(
119
            'exception' => get_class($exception),
120
            'message'   => $exception->getMessage(),
121
            'stack'     => $exception->getTraceAsString(),
122
            'previous'  => self::getExceptionData($exception->getPrevious()),
123
        );
124
    }
0 ignored issues
show
Coding Style introduced by
Expected //end getExceptionData()
Loading history...
125
}
0 ignored issues
show
Coding Style introduced by
Expected //end class
Loading history...