Completed
Push — development ( 1b87d2...43bb99 )
by Thomas
06:02
created

htdocs/lib2/errorhandler.inc.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/***************************************************************************
3
 * for license information see LICENSE.md
4
 *
5
 *
6
 *  This is included from both lib1 and lib2.
7
 ***************************************************************************/
8
9
$error_handled = false;
10
11
function register_errorhandlers()
12
{
13
    global $opt;
14
15
    if (isset($opt['gui']) && $opt['gui'] == GUI_HTML) {
16
        set_error_handler('errorhandler', E_ERROR);
17
        register_shutdown_function('shutdownhandler');
18
    }
19
}
20
21
/**
22
 * @param $errno
23
 * @param $errstr
24
 * @param $errfile
25
 * @param $errline
26
 */
27
function errorhandler($errno, $errstr, $errfile, $errline)
28
{
29
    // will catch a few runtime errors
30
31
    global $error_handled;
32
33
    if (!$error_handled) {
34
        $error_handled = true;
35
        $errtitle = 'PHP-Fehler';
36
37
        $error = "($errno) $errstr at line $errline in $errfile";
38
        php_errormail($error);
39
40
        if (display_error()) {
41
            $errmsg = $error;
42
        } else {
43
            $errmsg = '';
44
        }
45
46
        require __DIR__ . '/../html/error.php';
47
        exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function errorhandler() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
48
    }
49
}
50
51
function shutdownhandler()
52
{
53
    // see http://stackoverflow.com/questions/1900208/php-custom-error-handler-handling-parse-fatal-errors
54
    //
55
    // will catch anything but parse errors
56
57
    global $error_handled;
58
59
    if (!$error_handled &&
60
        function_exists('error_get_last') && /* PHP >= 5.2.0 */
61
        ($error = error_get_last()) &&
62
        in_array(
63
            $error['type'],
64
            [
65
            E_ERROR,
66
            E_CORE_ERROR,
67
            E_COMPILE_ERROR,
68
            E_USER_ERROR,
69
            ]
70
        )
71
    ) {
72
        $error_handled = true;
73
74
        $error = '(' . $error['type'] . ') ' . $error['message'] .
75
            ' at line ' . $error['line'] . ' of ' . $error['file'];
76
        php_errormail($error);
77
78
        $errtitle = 'PHP-Fehler';
79
        $errmsg = '';
80
        if (display_error()) {
81
            $errmsg = $error;
82
        }
83
84
        require __DIR__ . '/../html/error.php';
85
    }
86
}
87
88
/**
89
 * @return bool
90
 */
91
function display_error()
92
{
93
    global $opt, $debug_page;
94
95
    return (isset($opt['db']['error']['display']) && $opt['db']['error']['display']) ||
96
    (isset($debug_page) && $debug_page);
97
}
98
99
/**
100
 * @param $errmsg
101
 */
102
function php_errormail($errmsg)
103
{
104
    global $opt, $sql_errormail, $absolute_server_URI;
105
106
    $sendMail = true;
107
    $subject = '[' . $opt['page']['domain'] . '] PHP error';
108
109
    if (isset($opt['db']['error']['mail']) && $opt['db']['error']['mail'] != '') {
110
        $sendMail = mb_send_mail($opt['db']['error']['mail'], $subject, $errmsg);
111
    } elseif (isset($sql_errormail) && $sql_errormail != '') {
112
        $sendMail = mb_send_mail($sql_errormail, $subject, $errmsg);
113
    }
114
115
    if ($sendMail === false) {
116
        // @todo implement logging
117
        // throw new \RuntimeException('the E-Mail can not be send.');
118
    }
119
}
120
121
/**
122
 * throttle admin error mails;
123
 * currently used only for SQL errors and warnings
124
 *
125
 * @param $to
126
 * @param string $errortype
127
 * @param string $message
128
 * @param $headers
129
 * @return bool
130
 */
131
function admin_errormail($to, $errortype, $message, $headers)
132
{
133
    global $opt;
134
    $errorlog_dir = __DIR__ . '/../var/errorlog';
135
    $errorlog_path = $errorlog_dir . '/errorlog-' . date('Y-m-d');
136
137
    $error_mail_limit = 32768;    // send max 32 KB = ca. 5-20 errors per day/logfile
138
139
    // All errors which may happen here are ignored, to avoid error recursions.
140
141
    if (!is_dir($errorlog_dir)) {
142
        @mkdir($errorlog_dir);
143
    }
144
    $old_logsize = @filesize($errorlog_path) + 0;
145
    $msg = date('Y-m-d H:i:s.u') . ' ' . $errortype . "\n" . $message . "\n" .
146
        "-------------------------------------------------------------------------\n\n";
147
    try {
148
        error_log(
149
            $msg,
150
            3, // log to file
151
            $errorlog_path
152
        );
153
    } catch (Exception $e) {
154
        // @todo implement logging
155
    }
156
    // @filesize() may still return the old size here, because logging takes place
157
    // asynchronously. Instead we calculate the new size:
158
    $new_logsize = $old_logsize + strlen($msg);
159
160
    if ($old_logsize < $error_mail_limit && $new_logsize >= $error_mail_limit) {
161
        mb_send_mail(
162
            $to,
163
            'too many ' . $errortype,
164
            'Errors/Warnings are recorded in ' . $errorlog_path . ".\n" .
165
            "Email Reporting is DISABLED for today now. Please check the logfile\n" .
166
            'and RENAME or delete it when done, so that logging is re-enabled.',
167
            $headers
168
        );
169
170
        return false;
171
    }
172
173
    return ($old_logsize < $error_mail_limit);
174
}
175