Passed
Push — develop ( a00a1e...e4dd64 )
by Портнов
04:30
created

Notifications   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 28
eloc 114
c 1
b 0
f 0
dl 0
loc 201
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A sendTestMail() 0 10 3
A __construct() 0 17 3
A checkConnection() 0 10 2
A testConnectionPHPMailer() 0 9 2
B sendMail() 0 31 7
A testConnectionMSMTP() 0 5 1
A getMailSender() 0 33 5
A configure() 0 35 5
1
<?php
2
/*
3
 * MikoPBX - free phone system for small business
4
 * Copyright (C) 2017-2020 Alexey Portnov and Nikolay Beketov
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with this program.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
namespace MikoPBX\Core\System;
21
22
use PHPMailer\PHPMailer\PHPMailer;
23
use Throwable;
24
25
/**
26
 * Уведомления.
27
 */
28
class Notifications
29
{
30
    public const TYPE_MSMTP = 'MSMTP';
31
    public const TYPE_PHP_MAILER = 'PHP_MAILER';
32
    private array $settings;
33
    private bool  $enableNotifications;
34
    private string $fromAddres;
35
    private string $fromName;
36
37
    /**
38
     * Notifications constructor.
39
     */
40
    public function __construct()
41
    {
42
        $mikoPBXConfig  = new MikoPBXConfig();
43
        $this->settings = $mikoPBXConfig->getGeneralSettings();
44
        $this->enableNotifications = $this->settings['MailEnableNotifications'] === '1';
45
46
        $mailSMTPSenderAddress = $this->settings['MailSMTPSenderAddress'] ?? '';
47
        if (!empty($mailSMTPSenderAddress)) {
48
            $this->fromAddres = $mailSMTPSenderAddress;
49
        } else {
50
            $this->fromAddres = $this->settings['MailSMTPUsername'];
51
        }
52
53
        if (empty($this->settings['MailSMTPFromUsername'])) {
54
            $this->fromName = 'MikoPBX Notification';
55
        } else {
56
            $this->fromName = $this->settings['MailSMTPFromUsername'];
57
        }
58
    }
59
60
    /**
61
     * Возвращает инициализированный объект PHPMailer.
62
     * @return PHPMailer
63
     */
64
    public function getMailSender():PHPMailer
65
    {
66
        $mail = new PHPMailer();
67
        $mail->isSMTP();
68
        $mail->SMTPDebug = 0;
69
        $mail->Timeout   = 2;
70
        $mail->Host = $this->settings['MailSMTPHost'];
71
        if ($this->settings["MailSMTPUseTLS"] === "1") {
72
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
73
            // $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
74
        } else {
75
            $mail->SMTPSecure = '';
76
        }
77
        if (empty($this->settings['MailSMTPUsername']) && empty($this->settings['MailSMTPPassword'])) {
78
            $mail->SMTPAuth = false;
79
        } else {
80
            $mail->SMTPAuth = true;
81
            $mail->Username = $this->settings['MailSMTPUsername'];
82
            $mail->Password = $this->settings['MailSMTPPassword'];
83
            if ($this->settings["MailSMTPCertCheck"] !== '1') {
84
                $mail->SMTPOptions = [
85
                    'ssl' => [
86
                        'verify_peer'       => false,
87
                        'verify_peer_name'  => false,
88
                        'allow_self_signed' => true,
89
                    ],
90
                ];
91
            }
92
        }
93
        $mail->Port    = (integer)$this->settings['MailSMTPPort'];
94
        $mail->CharSet = 'UTF-8';
95
96
        return $mail;
97
    }
98
99
    public static function checkConnection($type):bool
100
    {
101
        $timeoutPath = Util::which('timeout');
102
        $phpPath = Util::which('php');
103
        $result  = Processes::mwExec("$timeoutPath 1 $phpPath -f /etc/rc/emailTestConnection.php ".$type);
104
        if($result !== 0 ){
105
            Util::sysLogMsg('PHPMailer', 'Error connect to SMTP server... ('. $type.')', LOG_ERR);
106
        }
107
108
        return ($result === 0);
109
    }
110
111
    /**
112
     * Отправка сообщения с использованием PHPMailer
113
     *
114
     * @param      $to
115
     * @param        $subject
116
     * @param        $message
117
     * @param string $filename
118
     *
119
     * @return bool
120
     */
121
    public function sendMail($to, $subject, $message, string $filename = ''):bool
122
    {
123
        if (! $this->enableNotifications) {
124
            return false;
125
        }
126
        $messages = [];
127
        try {
128
            $mail = $this->getMailSender();
129
            $mail->setFrom($this->fromAddres, $this->fromName);
130
            $mail->addAddress($to);
131
            if (file_exists($filename)) {
132
                $mail->addAttachment($filename);
133
            }
134
            $mail->isHTML(true);
135
            $mail->Subject = $subject;
136
            $mail->Body    = $message;
137
138
            if(!self::checkConnection(self::TYPE_PHP_MAILER)){
139
                return false;
140
            }
141
            if ( ! $mail->send()) {
142
                $messages[] = $mail->ErrorInfo;
143
            }
144
        } catch (Throwable $e) {
145
            $messages[] = $e->getMessage();
146
        }
147
        if (count($messages)>0) {
148
            Util::sysLogMsg('PHPMailer', implode(' ', $messages), LOG_ERR);
149
            return false;
150
        }
151
        return true;
152
    }
153
154
    /**
155
     * Отправка тестового сообщения.
156
     * @return bool
157
     */
158
    public function sendTestMail(): bool{
159
        if(!self::checkConnection(self::TYPE_PHP_MAILER)){
160
            return false;
161
        }
162
        if(!self::checkConnection(self::TYPE_MSMTP)){
163
            return false;
164
        }
165
        $systemNotificationsEmail = $this->settings['SystemNotificationsEmail'];
166
        $result = $this->sendMail($systemNotificationsEmail, 'Test mail from MIKO PBX', '<b>Test message</b><hr>');
167
        return ($result===true);
168
    }
169
170
    public static function testConnectionMSMTP():bool
171
    {
172
        $path = Util::which('msmtp');
173
        $result = Processes::mwExec("$path --file=/etc/msmtp.conf -S --timeout 1", $out);
174
        return ($result === 0);
175
    }
176
177
    public function testConnectionPHPMailer():bool
178
    {
179
        $mail = $this->getMailSender();
180
        try {
181
            $result = $mail->smtpConnect();
182
        }catch (\Exception $e){
183
            $result = false;
184
        }
185
        return $result;
186
    }
187
188
189
190
    /**
191
     * Настройка msmtp.
192
     *
193
     */
194
    public function configure(): void
195
    {
196
        $conf = "defaults\n" .
197
            "auth       on\n" .
198
            "timeout    2\n" .
199
            "syslog     on\n\n";
200
        $MailSMTPUseTLS=$this->settings["MailSMTPUseTLS"]??'0';
201
        if ($MailSMTPUseTLS === "1") {
202
            $conf .= "tls on\n";
203
            $conf .= "tls_starttls on\n";
204
            $MailSMTPCertCheck = $this->settings["MailSMTPCertCheck"]??'0';
205
            if ($MailSMTPCertCheck === '1') {
206
                $conf .= "tls_certcheck on\n";
207
                $conf .= "tls_trust_file /etc/ssl/certs/ca-certificates.crt\n";
208
            } else {
209
                $conf .= "tls_certcheck off\n";
210
            }
211
            $conf .= "\n";
212
        }
213
214
        $conf .= "account     general\n";
215
        $conf .= "host        {$this->settings['MailSMTPHost']}\n";
216
        $conf .= "port        {$this->settings['MailSMTPPort']}\n";
217
        $conf .= "from        {$this->fromAddres}\n";
218
        if (empty($this->settings['MailSMTPUsername']) && empty($this->settings['MailSMTPPassword'])) {
219
            $conf .= "auth        off\n";
220
        } else {
221
            $conf .= "user        {$this->settings['MailSMTPUsername']}\n";
222
            $conf .= "password    {$this->settings['MailSMTPPassword']}\n\n";
223
        }
224
225
        $conf .= "account default : general\n";
226
227
        Util::fileWriteContent("/etc/msmtp.conf", $conf);
228
        chmod("/etc/msmtp.conf", 384);
229
    }
230
}