1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Omnimail; |
4
|
|
|
|
5
|
|
|
use Http\Client\HttpClient; |
6
|
|
|
use Mailgun\Messages\Exceptions\InvalidParameter; |
7
|
|
|
use Mailgun\Messages\MessageBuilder; |
8
|
|
|
use Omnimail\Exception\EmailDeliveryException; |
9
|
|
|
use Omnimail\Exception\Exception; |
10
|
|
|
use Omnimail\Exception\InvalidRequestException; |
11
|
|
|
use Omnimail\Exception\UnauthorizedException; |
12
|
|
|
use Psr\Log\LoggerInterface; |
13
|
|
|
use Mailgun\Mailgun as MailgunAPI; |
14
|
|
|
|
15
|
|
|
class Mailgun implements MailerInterface |
16
|
|
|
{ |
17
|
|
|
protected $apiKey; |
18
|
|
|
protected $domain; |
19
|
|
|
protected $mailgun; |
20
|
|
|
protected $logger; |
21
|
|
|
protected $httpClient; |
22
|
|
|
protected $tmpfiles = []; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @param string $apiKey |
26
|
|
|
* @param string $domain |
27
|
|
|
* @param LoggerInterface|null $logger |
28
|
|
|
* @param HttpClient $httpClient |
29
|
|
|
*/ |
30
|
|
|
public function __construct( |
31
|
|
|
$apiKey = null, |
32
|
|
|
$domain = null, |
33
|
|
|
LoggerInterface $logger = null, |
34
|
1 |
|
HttpClient $httpClient = null |
35
|
|
|
) { |
36
|
1 |
|
$this->apiKey = $apiKey; |
37
|
|
|
$this->domain = $domain; |
38
|
|
|
$this->logger = $logger; |
39
|
1 |
|
$this->httpClient = $httpClient; |
40
|
|
|
$this->mailgun = new MailgunAPI($this->apiKey, $this->httpClient); |
41
|
1 |
|
} |
42
|
1 |
|
|
43
|
|
|
public function getApiKey() |
44
|
|
|
{ |
45
|
|
|
return $this->apiKey; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
public function setApiKey($apiKey) |
49
|
|
|
{ |
50
|
|
|
$this->apiKey = $apiKey; |
51
|
|
|
$this->mailgun = new MailgunAPI($this->apiKey, $this->httpClient); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
public function getDomain() |
55
|
|
|
{ |
56
|
|
|
return $this->domain; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
public function setDomain($domain) |
60
|
|
|
{ |
61
|
|
|
$this->domain = $domain; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
public function getLogger() |
65
|
|
|
{ |
66
|
|
|
return $this->logger; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
public function setLogger($logger) |
70
|
|
|
{ |
71
|
4 |
|
$this->logger = $logger; |
72
|
|
|
} |
73
|
4 |
|
|
74
|
4 |
|
public function getHttpClient() |
75
|
4 |
|
{ |
76
|
4 |
|
return $this->httpClient; |
77
|
4 |
|
} |
78
|
4 |
|
|
79
|
|
|
public function setHttpClient($httpClient) |
80
|
2 |
|
{ |
81
|
|
|
$this->httpClient = $httpClient; |
82
|
|
|
$this->mailgun = new MailgunAPI($this->apiKey, $this->httpClient); |
83
|
2 |
|
} |
84
|
|
|
|
85
|
2 |
|
/** |
86
|
2 |
|
* @param EmailInterface $email |
87
|
2 |
|
* @throws EmailDeliveryException |
88
|
|
|
* @throws Exception |
89
|
|
|
* @throws InvalidRequestException |
90
|
|
|
* @throws UnauthorizedException |
91
|
2 |
|
*/ |
92
|
|
|
public function send(EmailInterface $email) |
93
|
2 |
|
{ |
94
|
|
|
try { |
95
|
|
|
$builder = $this->mailgun->MessageBuilder(); |
|
|
|
|
96
|
|
|
|
97
|
2 |
|
if ($email->getTos()) { |
98
|
|
|
foreach ($email->getTos() as $recipient) { |
99
|
|
|
$builder->addToRecipient($this->mapEmails($email->getTos())); |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
|
103
|
2 |
|
$builder->setFromAddress($this->mapEmail($email->getFrom())); |
104
|
|
|
|
105
|
|
|
if ($email->getReplyTos()) { |
106
|
|
|
$builder->setReplyToAddress($this->mapEmails($email->getReplyTos())); |
107
|
|
|
} |
108
|
|
|
|
109
|
2 |
|
if ($email->getCcs()) { |
110
|
2 |
|
foreach ($email->getCcs() as $recipient) { |
111
|
|
|
$builder->addCcRecipient($this->mapEmail($recipient)); |
112
|
|
|
} |
113
|
2 |
|
} |
114
|
2 |
|
|
115
|
|
|
if ($email->getBccs()) { |
116
|
|
|
foreach ($email->getBccs() as $recipient) { |
117
|
2 |
|
$builder->addBccRecipient($this->mapEmail($recipient)); |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
|
121
|
2 |
|
if ($email->getSubject()) { |
122
|
|
|
$builder->setSubject($email->getSubject()); |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
if ($email->getTextBody()) { |
126
|
2 |
|
$builder->setTextBody($email->getTextBody()); |
127
|
2 |
|
} |
128
|
2 |
|
|
129
|
2 |
|
if ($email->getHtmlBody()) { |
130
|
|
|
$builder->setHtmlBody($email->getHtmlBody()); |
131
|
|
|
} |
132
|
1 |
|
|
133
|
1 |
|
if ($email->getAttachments()) { |
134
|
1 |
|
$this->mapAttachments($email->getAttachments(), $builder); |
135
|
|
|
$this->mapInlineAttachments($email->getAttachments(), $builder); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
$result = $this->mailgun->post( |
|
|
|
|
139
|
|
|
"{$this->domain}/messages", |
140
|
|
|
$builder->getMessage(), |
141
|
|
|
$builder->getFiles() |
142
|
|
|
); |
143
|
|
|
|
144
|
|
|
switch ($result->http_response_code) { |
145
|
1 |
|
case 200: |
146
|
1 |
|
break; |
147
|
|
|
case 400: |
148
|
1 |
|
throw new InvalidRequestException; |
149
|
|
|
case 401: |
150
|
|
|
throw new UnauthorizedException; |
151
|
|
|
case 402: |
152
|
|
|
throw new EmailDeliveryException; |
153
|
1 |
|
default: |
154
|
1 |
|
throw new Exception('Unknown error', 603); |
155
|
|
|
} |
156
|
|
|
|
157
|
1 |
|
if ($this->logger) { |
158
|
1 |
|
$this->logger->info("Email sent: '{$email->getSubject()}'", $email->toArray()); |
159
|
2 |
|
} |
160
|
|
|
} catch (Exception $e) { |
161
|
1 |
|
if ($this->logger) { |
162
|
|
|
$this->logger->error("Email error: '{$e->getMessage()}'", $email->toArray()); |
163
|
|
|
} |
164
|
|
|
throw $e; |
165
|
|
|
} catch (\Exception $e) { |
166
|
|
|
if ($this->logger) { |
167
|
|
|
$this->logger->error("Email error: '{$e->getMessage()}'", $email->toArray()); |
168
|
2 |
|
} |
169
|
|
|
throw new Exception($e->getMessage(), $e->getCode(), $e); |
170
|
2 |
|
} finally { |
171
|
|
|
$this->removeTmpfiles(); |
172
|
|
|
} |
173
|
2 |
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* @param array $emails |
177
|
|
|
* @return string |
178
|
|
|
*/ |
179
|
|
|
private function mapEmails(array $emails) |
180
|
|
|
{ |
181
|
|
|
$returnValue = ''; |
182
|
|
|
foreach ($emails as $email) { |
183
|
|
|
$returnValue .= $this->mapEmail($email) . ', '; |
184
|
|
|
} |
185
|
|
|
return $returnValue ? substr($returnValue, 0, -2) : ''; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* @param array $email |
190
|
|
|
* @return string |
191
|
|
|
*/ |
192
|
|
|
private function mapEmail(array $email) |
193
|
|
|
{ |
194
|
|
|
return !empty($email['name']) ? "'{$email['name']}' <{$email['email']}>" : $email['email']; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* @param AttachmentInterface[]|array|null $attachments |
199
|
|
|
* @param MessageBuilder $builder |
200
|
|
|
* @return array|null |
201
|
|
|
*/ |
202
|
|
|
private function mapAttachments(array $attachments, MessageBuilder $builder) |
203
|
|
|
{ |
204
|
|
|
foreach ($attachments as $attachment) { |
205
|
|
|
if ($attachment->getContentId()) { |
206
|
|
|
continue; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
if ($attachment->getPath()) { |
210
|
|
|
$file = $attachment->getPath(); |
211
|
|
|
} elseif ($attachment->getContent()) { |
212
|
|
|
$this->addTmpfile($file = tmpfile()); |
213
|
|
|
fwrite($file, $attachment->getContent()); |
214
|
|
|
} else { |
215
|
|
|
continue; |
216
|
|
|
} |
217
|
|
|
$builder->addAttachment($file, $attachment->getName()); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
return null; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
private function addTmpfile($file) |
224
|
|
|
{ |
225
|
|
|
$this->tmpfiles[] = $file; |
226
|
|
|
} |
227
|
2 |
|
|
228
|
|
|
/** |
229
|
2 |
|
* @param AttachmentInterface[]|array|null $attachments |
230
|
2 |
|
* @param MessageBuilder $builder |
231
|
2 |
|
* @return void |
232
|
|
|
* @throws InvalidParameter |
233
|
2 |
|
*/ |
234
|
|
|
private function mapInlineAttachments(array $attachments, MessageBuilder $builder) |
235
|
|
|
{ |
236
|
|
|
foreach ($attachments as $attachment) { |
237
|
|
|
if (!$attachment->getContentId()) { |
238
|
|
|
continue; |
239
|
|
|
} |
240
|
2 |
|
|
241
|
|
|
if ($attachment->getPath()) { |
242
|
2 |
|
$file = $attachment->getPath(); |
243
|
|
|
} elseif ($attachment->getContent()) { |
244
|
|
|
$this->addTmpfile($file = tmpfile()); |
245
|
|
|
fwrite($file, $attachment->getContent()); |
246
|
|
|
} else { |
247
|
|
|
continue; |
248
|
|
|
} |
249
|
|
|
$builder->addInlineImage($file, $attachment->getContentId()); |
250
|
|
|
} |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
private function removeTmpfiles() |
254
|
|
|
{ |
255
|
|
|
foreach ($this->tmpfiles as $file) { |
256
|
|
|
fclose($file); |
257
|
|
|
} |
258
|
|
|
} |
259
|
|
|
} |
260
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.