Issues (10)

src/sender/Email.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Dongdavid\Notify\sender;
4
5
use Dongdavid\Notify\Exceptions\Exception;
6
use Dongdavid\Notify\Sender;
7
use PHPMailer\PHPMailer\PHPMailer;
8
use PHPMailer\PHPMailer\SMTP;
9
10
class Email extends Sender
11
{
12
    public function checkConfig()
13
    {
14
        if (!isset($this->config['host'])) {
15
            throw new \Exception('请传入邮箱服务器地址');
16
        }
17
18
        if (!isset($this->config['username'])) {
19
            throw new \Exception('请传入邮箱服务器认证账号');
20
        }
21
22
        if (!isset($this->config['password'])) {
23
            throw new \Exception('请传入邮箱服务器认证密码');
24
        }
25
26
        if (!isset($this->config['fromEmail'])) {
27
            throw new \Exception('请设置发件人邮箱');
28
        }
29
30
        if (!isset($this->config['fromName'])) {
31
            $this->config['fromName'] = $this->config['fromEmail'];
32
        }
33
34
        if (!isset($this->config['debug'])) {
35
            $this->config['debug'] = 0;
36
        }
37
        if (!isset($this->config['SMTPSecure'])) {
38
            $this->config['SMTPSecure'] = false;
39
            $this->config['SMTPOptions'] = [
40
                'ssl' => [
41
                    'verify_peer' => false,
42
                    'verify_peer_name' => false,
43
                    'allow_self_signed' => true,
44
                ],
45
            ];
46
        }
47
        if (!isset($this->config['SMTPOptions'])) {
48
            $this->config['SMTPOptions'] = [
49
                'ssl' => [
50
                    'verify_peer' => false,
51
                    'verify_peer_name' => false,
52
                    'allow_self_signed' => true,
53
                ],
54
            ];
55
        }
56
57
        if (!isset($this->config['port'])) {
58
            $this->config['port'] = 25;
59
        }
60
    }
61
62
    public function checkMsgFormate($msg)
63
    {
64
        if (!isset($msg['subject'])) {
65
            throw new \Exception('邮件主题未设置');
66
        }
67
68
        if (!isset($msg['body'])) {
69
            throw new \Exception('邮件正文未设置');
70
        }
71
72
        if (!isset($msg['to'])) {
73
            throw new \Exception('收件人未设置');
74
        } else {
75
            $msg['to'] = $this->checkEmailAddress($msg['to']);
76
        }
77
        if (isset($msg['cc'])) {
78
            $msg['cc'] = $this->checkEmailAddress($msg['cc']);
79
        }
80
        if (isset($msg['bcc'])) {
81
            $msg['bcc'] = $this->checkEmailAddress($msg['bcc']);
82
        }
83
        if (isset($msg['attachments'])) {
84
            $msg['attachments'] = $this->checkAttachments($msg['attachments']);
85
        }
86
87
        return $msg;
88
    }
89
90
    public function checkEmailAddress($emailAddresses)
91
    {
92
        if (is_string($emailAddresses)) {
93
            if (filter_var($emailAddresses, FILTER_VALIDATE_EMAIL)) {
94
                return [
95
                    ['email' => $emailAddresses, 'name' => $emailAddresses],
96
                ];
97
            } else {
98
                throw new \Exception('邮箱格式不正确:'.$emailAddresses);
99
            }
100
        } elseif (is_array($emailAddresses)) {
101
            foreach ($emailAddresses as &$emailAddress) {
102
                if (is_string($emailAddress)) {
103
                    $emailAddress = ['email' => $emailAddress, 'name' => $emailAddress];
104
                } else {
105
                    if (!isset($emailAddress['email'])) {
106
                        throw new Exception('缺失邮箱地址[email]');
107
                    }
108
                }
109
                if (!filter_var($emailAddress['email'], FILTER_VALIDATE_EMAIL)) {
110
                    throw new \Exception('邮箱格式不正确:'.$emailAddress);
111
                }
112
            }
113
114
            return $emailAddresses;
115
        }
116
    }
117
118
    public function checkAttachments($attachments)
119
    {
120
        if (is_string($attachments)) {
121
            $path = realpath($attachments);
122
            if (!file_exists($path)) {
123
                throw new \Exception('附件不存在:'.$attachments);
124
            }
125
            $attachments = [
126
                [
127
                    'filepath' => $path,
128
                    'filename' => basename($path),
129
                ],
130
            ];
131
        } elseif (is_array($attachments)) {
132
            foreach ($attachments as &$attachment) {
133
                if (is_string($attachment)) {
134
                    $attachment = [
135
                        'filename' => basename($attachment),
136
                        'filepath' => realpath($attachment),
137
                    ];
138
                }
139
                if (!file_exists($attachment['filepath'])) {
140
                    throw new \Exception('附件不存在:'.$attachment);
141
                }
142
            }
143
        } else {
144
            throw new \Exception('attachments参数格式错误');
145
        }
146
147
        return $attachments;
148
    }
149
150
    public function send($msg)
151
    {
152
        $msg = $this->checkMsgFormate($msg);
153
154
        return $this->sendMail($msg);
155
    }
156
157
    private function sendMail($msg)
158
    {
159
        $mail = new PHPMailer(true);
160
161
        try {
162
            //Server settings
163
            $mail->SMTPDebug = $this->config['debug'];  // Enable verbose debug output
164
            $mail->isSMTP();  // Set mailer to use SMTP
165
            $mail->Host = $this->config['host'];  // Specify main and backup SMTP servers
166
            $mail->SMTPAuth = true;  // Enable SMTP authentication
167
            $mail->Username = $this->config['username'];  // SMTP username
168
            $mail->Password = $this->config['password'];  // SMTP password
169
            $mail->SMTPSecure = $this->config['SMTPSecure'];  // Enable TLS encryption, `ssl` also accepted
170
            $mail->Port = $this->config['port'];  // TCP port to connect to
171
            $mail->CharSet = 'UTF-8';
172
            $mail->SMTPOptions = $this->config['SMTPOptions'];
173
            //Recipients
174
            $mail->setFrom($this->config['fromEmail'], $this->config['fromName']);
175
            if (isset($this->config['replyMail'])) {
176
                $mail->setReplyTo($this->config['replyMail']);
0 ignored issues
show
The method setReplyTo() does not exist on PHPMailer\PHPMailer\PHPMailer. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

176
                $mail->/** @scrutinizer ignore-call */ 
177
                       setReplyTo($this->config['replyMail']);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
177
            }
178
            if (isset($this->config['SMTPOptions'])) {
179
                $mail->SMTPOptions = $this->config['SMTPOptions'];
180
            }
181
            // touser
182
            if (isset($msg['to'])) {
183
                foreach ($msg['to'] as $t) {
184
                    $mail->addAddress($t['email'], $t['name']);
185
                }
186
            }
187
            // cc
188
            if (isset($msg['cc']) && is_string($msg['cc'])) {
189
                foreach ($msg['cc'] as $c) {
190
                    $mail->addCC($c['email'], $c['name']);
191
                }
192
            }
193
194
            // bcc
195
            if (isset($msg['bcc'])) {
196
                foreach ($msg['bcc'] as $bc) {
197
                    $mail->addBCC($bc['email'], $bc['name']);
198
                }
199
            }
200
201
            // Attachments
202
            if (isset($msg['attachments']) && !empty($msg['attachments'])) {
203
                foreach ($msg['attachments'] as $attachment) {
204
                    $mail->addAttachment($attachment['filepath'], $attachment['filename']);
205
                }
206
            }
207
            // Content
208
            $mail->isHTML(true); // Set email format to HTML
209
            $mail->Subject = $msg['subject'];
210
            $mail->Body = $msg['body'];
211
212
            $mail->AltBody = '请使用支持html的邮箱客户端,以取得更好的浏览体验';
213
            $r = $mail->send();
214
            if (!$r) {
215
                throw new \Exception('邮件发送失败:'.$mail->ErrorInfo);
216
            }
217
218
            return true;
219
        } catch (\Exception $e) {
220
            throw new \Exception('邮件发送失败:'.$e->getMessage().$e->getLine());
221
        }
222
    }
223
}
224