Passed
Push — development ( 2c0f7a...866d79 )
by Thomas
01:59
created

MailLog::processSysLog()   C

Complexity

Conditions 11
Paths 10

Size

Total Lines 118
Code Lines 76

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 76
nc 10
nop 0
dl 0
loc 118
rs 5.2653
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
 *  For license information see doc/license.txt
4
 *
5
 *
6
 *  Process system maillog to detect email delivery problems
7
 ***************************************************************************/
8
9
checkJob(new MailLog());
10
11
class MailLog
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
12
{
13
    public $name = 'maillog';
14
    public $interval = 600; // every 10 minutes
15
16
17
    public function run()
18
    {
19
        global $opt;
20
        if ($opt['system']['maillog']['syslog_db_host'] != '') {
21
            $this->processSysLog();
22
        }
23
    }
24
25
26
    public function processSysLog()
27
    {
28
        global $opt;
29
30
        // @todo change deprecated function
31
        $dbc = @mysql_connect(
32
            $opt['system']['maillog']['syslog_db_host'],
33
            $opt['system']['maillog']['syslog_db_user'],
34
            $opt['system']['maillog']['syslog_db_password'],
35
            true
36
        ); // use separate connection even if on same DB host
37
        if ($dbc === false) {
38
            echo $this->name . ": could not connect to syslog database\n";
39
40
            return;
41
        }
42
        if (@mysql_query("USE " . $opt['system']['maillog']['syslog_db_name'], $dbc) === false) {
43
            echo $this->name . ": could not open syslog database: " . mysql_error() . "\n";
44
45
            return;
46
        }
47
48
        $col_id = mysql_real_escape_string($opt['system']['maillog']['column']['id']);
49
        $col_message = mysql_real_escape_string($opt['system']['maillog']['column']['message']);
50
        $col_created = mysql_real_escape_string($opt['system']['maillog']['column']['created']);
51
        $col_hostname = mysql_real_escape_string($opt['system']['maillog']['column']['host_name']);
52
        $col_program = mysql_real_escape_string($opt['system']['maillog']['column']['program']);
53
54
        $maillog_where =
55
            '`' . $col_hostname . "`='" . mysql_real_escape_string($opt['system']['maillog']['syslog_oc_host']) . "' AND
56
            `" . $col_program . "` like '" . mysql_real_escape_string($opt['system']['maillog']['syslog_mta']) . "'";
57
58
        $rs = @mysql_query(
59
            '
60
            SELECT TIMESTAMPDIFF(DAY, MAX(' . $col_created . '), NOW())
61
            FROM `' . mysql_real_escape_string($opt['system']['maillog']['syslog_db_table']) . '`
62
            WHERE ' . $maillog_where
63
        );
64
        $r = mysql_fetch_row($rs);
65
        mysql_free_result($rs);
66
        if ($r[0] >= $opt['system']['maillog']['inactivity_warning']) {
67
            echo "email syslog has stalled\n";
68
69
            return;
70
        }
71
72
        $last_id = sql_value("SELECT `value` FROM `sysconfig` WHERE `name`='syslog_maillog_lastid'", 0);
73
        $last_date = sql_value("SELECT `value` FROM `sysconfig` WHERE `name`='syslog_maillog_lastdate'", "");
74
75
        // We check for both, new IDs and new creation dates, so that it still works
76
        // if the syslog DB is re-setup and IDs restarted from 1 (dates are not unique).
77
        //
78
        // It happened that old log entries were re-added as duplicates to the syslog table.
79
        // We solve this problem by ignoring entries with higher ID and older timestamp. Worst
80
        // case some entries with same timestamp as $last_date will be processed redundantly.
81
82
        $rs = @mysql_query(
83
            'SELECT `' . $col_id . '` `id`,
84
                      `' . $col_message . '` `message`,
85
                      `' . $col_created . '` `created`
86
                 FROM `' . mysql_real_escape_string($opt['system']['maillog']['syslog_db_table']) . '`
87
                WHERE `' . $col_created . "`>='" . mysql_real_escape_string($last_date) . "'
88
                  AND (`" . $col_id . "`>'" . mysql_real_escape_string(
89
                $last_id
90
            ) . "' OR `" . $col_created . "`>'" . mysql_real_escape_string($last_date) . "')
91
                  AND  " . $maillog_where . '
92
             ORDER BY `' . $col_created . '`,`' . $col_id . '`',
93
            $dbc
94
        );
95
        if ($rs === false) {
96
            echo $this->name . ": syslog query error (" . mysql_errno() . "): " . mysql_error() . "\n";
97
98
            return;
99
        }
100
101
        while ($logentry = mysql_fetch_assoc($rs)) {
102
            $message = $logentry['message']; // latin-1 charset
103
            $delivered = strpos($message, 'status=sent') > 0;
104
            $bounced = strpos($message, 'status=bounced') > 0;
105
            if ($delivered || $bounced) {
106
                if (preg_match('/ to=<(.+)>,/U', $message, $matches)) {
107
                    $emailadr = $matches[1];
108
                    if ($delivered) {
109
                        sql(
110
                            "UPDATE `user` SET `email_problems`=0
111
                              WHERE `email`='&1'",
112
                            $emailadr
113
                        );
114
                    } else {
115
                        if ($bounced) {  // maximum one bounce per day is counted, to filter out temporary problems
116
                            sql(
117
                                "UPDATE `user` SET `email_problems`=`email_problems`+1, `last_email_problem`='&2'
118
                              WHERE `email`='&1' AND IFNULL(`last_email_problem`,'') < '&2'",
119
                                $emailadr,
120
                                $logentry['created']
121
                            );
122
                        }
123
                    }
124
                } else {
125
                    echo $this->name . ': no email address found for record ID ' . $logentry['id'] . "\n";
126
                }
127
            }
128
            $last_id = $logentry['id'];
129
            $last_date = $logentry['created'];
130
        }
131
        mysql_free_result($rs);
132
133
        sql(
134
            "INSERT INTO `sysconfig` (`name`, `value`) VALUES ('syslog_maillog_lastid','&1')
135
             ON DUPLICATE KEY UPDATE `value`='&1'",
136
            $last_id
137
        );
138
        sql(
139
            "INSERT INTO `sysconfig` (`name`, `value`) VALUES ('syslog_maillog_lastdate','&1')
140
             ON DUPLICATE KEY UPDATE `value`='&1'",
141
            $last_date
142
        );
143
    }
144
}
145