1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @package CleverStyle Framework |
4
|
|
|
* @author Nazar Mokrynskyi <[email protected]> |
5
|
|
|
* @copyright Copyright (c) 2011-2016, Nazar Mokrynskyi |
6
|
|
|
* @license MIT License, see license.txt |
7
|
|
|
*/ |
8
|
|
|
namespace cs; |
9
|
|
|
use |
10
|
|
|
h, |
11
|
|
|
PHPMailer, |
12
|
|
|
phpmailerException; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* @method static $this instance($check = false) |
16
|
|
|
*/ |
17
|
|
|
class Mail { |
18
|
|
|
use Singleton; |
19
|
|
|
/** |
20
|
|
|
* Sending of email |
21
|
|
|
* |
22
|
|
|
* @param array|string|string[] $email if emails without names - string (may be several emails separated by comma) or |
23
|
|
|
* 1-dimensional array(<i>email</i>)<br> |
24
|
|
|
* 2-dimensional of emails or array(<i>email</i>, <i>name</i>) must be given |
25
|
|
|
* @param string $subject Mail subject |
26
|
|
|
* @param string $body html body |
27
|
|
|
* @param string|null $body_text plain text body |
28
|
|
|
* @param array|null|string $attachments 1- or 2-dimensional array of array(<i>path</i>, <i>name</i>) or simply string with path to the file in |
29
|
|
|
* file system |
30
|
|
|
* @param array|null|string|string[] $reply_to Similar to <b>$email</b>, but multiple emails are not supported |
31
|
|
|
* @param bool|string $signature <b>true</b> - add system signature<br> |
32
|
|
|
* <b>false</b> - without signature<br> |
33
|
|
|
* <b>string</b> - custom signature |
34
|
|
|
* |
35
|
|
|
* @return bool |
36
|
|
|
*/ |
37
|
|
|
public function send_to ($email, $subject, $body, $body_text = null, $attachments = null, $reply_to = null, $signature = true) { |
38
|
|
|
if (!$email || !$subject || !$body) { |
39
|
|
|
return false; |
40
|
|
|
} |
41
|
|
|
$PHPMailer = $this->phpmailer_instance(); |
42
|
|
|
foreach ($this->normalize_email($email) as $e) { |
43
|
|
|
$PHPMailer->addAddress(...$e); |
44
|
|
|
} |
45
|
|
|
foreach ($this->normalize_email($reply_to) as $r) { |
|
|
|
|
46
|
|
|
$PHPMailer->addReplyTo(...$r); |
47
|
|
|
} |
48
|
|
|
foreach ($this->normalize_attachment($attachments) as $a) { |
49
|
|
|
try { |
50
|
|
|
$PHPMailer->addAttachment(...$a); |
51
|
|
|
} catch (phpmailerException $e) { |
52
|
|
|
trigger_error($e->getMessage(), E_USER_WARNING); |
53
|
|
|
} |
54
|
|
|
} |
55
|
|
|
$PHPMailer->Subject = $subject; |
56
|
|
|
$signature = $this->make_signature($signature); |
57
|
|
|
$PHPMailer->Body = $this->normalize_body($body, $signature); |
58
|
|
|
if ($body_text) { |
59
|
|
|
$PHPMailer->AltBody = $body_text.strip_tags($signature); |
60
|
|
|
} |
61
|
|
|
try { |
62
|
|
|
$result = $PHPMailer->send(); |
63
|
|
|
} catch (phpmailerException $e) { |
64
|
|
|
trigger_error($e->getMessage(), E_USER_WARNING); |
65
|
|
|
$result = false; |
66
|
|
|
} |
67
|
|
|
return $result; |
68
|
|
|
} |
69
|
|
|
/** |
70
|
|
|
* Create PHPMailer instance with parameters according to system configuration |
71
|
|
|
* |
72
|
|
|
* @return PHPMailer |
73
|
|
|
*/ |
74
|
|
|
protected function phpmailer_instance () { |
75
|
|
|
$PHPMailer = new PHPMailer(true); |
76
|
|
|
$Config = Config::instance(); |
77
|
|
|
if ($Config->core['smtp']) { |
78
|
|
|
$PHPMailer->isSMTP(); |
79
|
|
|
$PHPMailer->Host = $Config->core['smtp_host']; |
80
|
|
|
$PHPMailer->Port = $Config->core['smtp_port']; |
81
|
|
|
$PHPMailer->SMTPSecure = $Config->core['smtp_secure']; |
82
|
|
|
if ($Config->core['smtp_auth']) { |
83
|
|
|
$PHPMailer->SMTPAuth = true; |
84
|
|
|
$PHPMailer->Username = $Config->core['smtp_user']; |
85
|
|
|
$PHPMailer->Password = $Config->core['smtp_password']; |
86
|
|
|
} |
87
|
|
|
} |
88
|
|
|
$PHPMailer->From = $Config->core['mail_from']; |
89
|
|
|
$PHPMailer->FromName = get_core_ml_text('mail_from_name'); |
90
|
|
|
$PHPMailer->CharSet = 'utf-8'; |
91
|
|
|
$PHPMailer->isHTML(); |
92
|
|
|
return $PHPMailer; |
93
|
|
|
} |
94
|
|
|
/** |
95
|
|
|
* @param array|string|string[] $email |
96
|
|
|
* |
97
|
|
|
* @return string[][] |
98
|
|
|
*/ |
99
|
|
|
protected function normalize_email ($email) { |
100
|
|
|
if (!$email) { |
101
|
|
|
return []; |
102
|
|
|
} |
103
|
|
|
if (!is_array($email)) { |
104
|
|
|
$email = _trim(explode(',', $email)); |
105
|
|
|
} elseif (!is_array($email[0])) { |
106
|
|
|
$email = [$email]; |
107
|
|
|
} |
108
|
|
|
return _array($email); |
109
|
|
|
} |
110
|
|
|
protected function make_signature ($signature) { |
|
|
|
|
111
|
|
|
if ($signature === true) { |
112
|
|
|
$signature = get_core_ml_text('mail_signature'); |
113
|
|
|
return $signature ? "<br>\n<br>\n-- \n<br>$signature" : ''; |
114
|
|
|
} |
115
|
|
|
return $signature ? "<br>\n<br>\n-- \n<br>".xap($signature, true) : ''; |
116
|
|
|
} |
117
|
|
|
/** |
118
|
|
|
* @param string $body |
119
|
|
|
* @param string $signature |
120
|
|
|
* |
121
|
|
|
* @return string |
122
|
|
|
*/ |
123
|
|
|
protected function normalize_body ($body, $signature) { |
124
|
|
|
if (strpos($body, '<!doctype') === 0 && strpos($body, '<body') !== false) { |
125
|
|
|
$body = "<!doctype html>\n$body"; |
126
|
|
|
} |
127
|
|
|
if (strpos($body, '<html') === false) { |
128
|
|
|
if (strpos($body, '<body') === false) { |
129
|
|
|
$body = h::body($body.$signature); |
130
|
|
|
} else { |
131
|
|
|
$body = str_replace('</body>', "$signature</body>", $body); |
132
|
|
|
} |
133
|
|
|
$body = h::html( |
134
|
|
|
h::{'head meta'}( |
135
|
|
|
[ |
136
|
|
|
'content' => 'text/html; charset=utf-8', |
137
|
|
|
'http-equiv' => 'Content-Type' |
138
|
|
|
] |
139
|
|
|
). |
140
|
|
|
$body |
141
|
|
|
); |
142
|
|
|
} else { |
143
|
|
|
$body = str_replace('</body>', "$signature</body>", $body); |
144
|
|
|
} |
145
|
|
|
return $body; |
146
|
|
|
} |
147
|
|
|
/** |
148
|
|
|
* @param array|null|string $attachments |
149
|
|
|
* |
150
|
|
|
* @return array |
151
|
|
|
*/ |
152
|
|
|
protected function normalize_attachment ($attachments) { |
153
|
|
|
if (!$attachments) { |
154
|
|
|
return []; |
155
|
|
|
} |
156
|
|
|
if (!is_array($attachments) || !is_array($attachments[0])) { |
157
|
|
|
$attachments = [$attachments]; |
158
|
|
|
} |
159
|
|
|
return _array($attachments); |
160
|
|
|
} |
161
|
|
|
} |
162
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.