1
|
|
|
<?PHP |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* Copyright (C) 2013-2016 Mailgun |
5
|
|
|
* |
6
|
|
|
* This software may be modified and distributed under the terms |
7
|
|
|
* of the MIT license. See the LICENSE file for details. |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
namespace Mailgun\Messages; |
11
|
|
|
|
12
|
|
|
use Mailgun\Constants\Api; |
13
|
|
|
use Mailgun\Constants\ExceptionMessages; |
14
|
|
|
use Mailgun\Messages\Exceptions\InvalidParameter; |
15
|
|
|
use Mailgun\Messages\Exceptions\TooManyParameters; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* This class is used for composing a properly formed |
19
|
|
|
* message object. Dealing with arrays can be cumbersome, |
20
|
|
|
* this class makes the process easier. See the official |
21
|
|
|
* documentation (link below) for usage instructions. |
22
|
|
|
* |
23
|
|
|
* @see https://github.com/mailgun/mailgun-php/blob/master/src/Mailgun/Messages/README.md |
24
|
|
|
*/ |
25
|
|
|
class MessageBuilder |
26
|
|
|
{ |
27
|
|
|
/** |
28
|
|
|
* @var array |
29
|
|
|
*/ |
30
|
|
|
protected $message = []; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @var array |
34
|
|
|
*/ |
35
|
|
|
protected $variables = []; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @var array |
39
|
|
|
*/ |
40
|
|
|
protected $files = []; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var array |
44
|
|
|
*/ |
45
|
|
|
protected $counters = [ |
46
|
|
|
'recipients' => [ |
47
|
|
|
'to' => 0, |
48
|
|
|
'cc' => 0, |
49
|
|
|
'bcc' => 0, |
50
|
|
|
], |
51
|
|
|
'attributes' => [ |
52
|
|
|
'attachment' => 0, |
53
|
|
|
'campaign_id' => 0, |
54
|
|
|
'custom_option' => 0, |
55
|
|
|
'tag' => 0, |
56
|
|
|
], |
57
|
|
|
]; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @param array $params |
61
|
|
|
* @param string $key |
62
|
|
|
* @param mixed $default |
63
|
|
|
* |
64
|
|
|
* @return mixed |
65
|
|
|
*/ |
66
|
21 |
|
protected function safeGet($params, $key, $default) |
67
|
|
|
{ |
68
|
21 |
|
if (array_key_exists($key, $params)) { |
69
|
17 |
|
return $params[$key]; |
70
|
|
|
} |
71
|
|
|
|
72
|
5 |
|
return $default; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* @param array $params |
77
|
|
|
* |
78
|
|
|
* @return mixed|string |
79
|
|
|
*/ |
80
|
21 |
|
protected function getFullName($params) |
81
|
|
|
{ |
82
|
21 |
|
if (array_key_exists('first', $params)) { |
83
|
17 |
|
$first = $this->safeGet($params, 'first', ''); |
84
|
17 |
|
$last = $this->safeGet($params, 'last', ''); |
85
|
|
|
|
86
|
17 |
|
return trim("$first $last"); |
87
|
|
|
} |
88
|
|
|
|
89
|
5 |
|
return $this->safeGet($params, 'full_name', ''); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* @param string $address |
94
|
|
|
* @param array $variables |
95
|
|
|
* |
96
|
|
|
* @return string |
97
|
|
|
*/ |
98
|
21 |
|
protected function parseAddress($address, $variables) |
99
|
|
|
{ |
100
|
21 |
|
if (!is_array($variables)) { |
101
|
|
|
return $address; |
102
|
|
|
} |
103
|
21 |
|
$fullName = $this->getFullName($variables); |
104
|
21 |
|
if ($fullName != null) { |
105
|
17 |
|
return "'$fullName' <$address>"; |
106
|
|
|
} |
107
|
|
|
|
108
|
5 |
|
return $address; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @param string $headerName |
113
|
|
|
* @param string $address |
114
|
|
|
* @param array $variables |
115
|
|
|
*/ |
116
|
11 |
|
protected function addRecipient($headerName, $address, $variables) |
117
|
|
|
{ |
118
|
11 |
|
$compiledAddress = $this->parseAddress($address, $variables); |
119
|
|
|
|
120
|
11 |
|
if ($headerName === 'h:reply-to') { |
121
|
1 |
|
$this->message[$headerName] = $compiledAddress; |
122
|
11 |
|
} elseif (isset($this->message[$headerName])) { |
123
|
1 |
|
array_push($this->message[$headerName], $compiledAddress); |
124
|
1 |
|
} else { |
125
|
10 |
|
$this->message[$headerName] = [$compiledAddress]; |
126
|
|
|
} |
127
|
11 |
|
if (array_key_exists($headerName, $this->counters['recipients'])) { |
128
|
9 |
|
$this->counters['recipients'][$headerName] += 1; |
129
|
9 |
|
} |
130
|
11 |
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* @param string $address |
134
|
|
|
* @param array|null $variables |
135
|
|
|
* |
136
|
|
|
* @throws TooManyParameters |
137
|
|
|
* |
138
|
|
|
* @return mixed |
139
|
|
|
*/ |
140
|
13 |
View Code Duplication |
public function addToRecipient($address, $variables = null) |
|
|
|
|
141
|
|
|
{ |
142
|
13 |
|
if ($this->counters['recipients']['to'] > Api::RECIPIENT_COUNT_LIMIT) { |
143
|
|
|
throw new TooManyParameters(ExceptionMessages::TOO_MANY_PARAMETERS_RECIPIENT); |
144
|
|
|
} |
145
|
|
|
|
146
|
13 |
|
$variables = is_array($variables) ? $variables : []; |
147
|
|
|
|
148
|
13 |
|
$this->addRecipient('to', $address, $variables); |
149
|
|
|
|
150
|
13 |
|
return end($this->message['to']); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* @param string $address |
155
|
|
|
* @param array|null $variables |
156
|
|
|
* |
157
|
|
|
* @throws TooManyParameters |
158
|
|
|
* |
159
|
|
|
* @return mixed |
160
|
|
|
*/ |
161
|
4 |
View Code Duplication |
public function addCcRecipient($address, $variables = null) |
|
|
|
|
162
|
|
|
{ |
163
|
4 |
|
if ($this->counters['recipients']['cc'] > Api::RECIPIENT_COUNT_LIMIT) { |
164
|
|
|
throw new TooManyParameters(ExceptionMessages::TOO_MANY_PARAMETERS_RECIPIENT); |
165
|
|
|
} |
166
|
|
|
|
167
|
4 |
|
$variables = is_array($variables) ? $variables : []; |
168
|
|
|
|
169
|
4 |
|
$this->addRecipient('cc', $address, $variables); |
170
|
|
|
|
171
|
4 |
|
return end($this->message['cc']); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* @param string $address |
176
|
|
|
* @param array|null $variables |
177
|
|
|
* |
178
|
|
|
* @throws TooManyParameters |
179
|
|
|
* |
180
|
|
|
* @return mixed |
181
|
|
|
*/ |
182
|
4 |
View Code Duplication |
public function addBccRecipient($address, $variables = null) |
|
|
|
|
183
|
|
|
{ |
184
|
4 |
|
if ($this->counters['recipients']['bcc'] > Api::RECIPIENT_COUNT_LIMIT) { |
185
|
|
|
throw new TooManyParameters(ExceptionMessages::TOO_MANY_PARAMETERS_RECIPIENT); |
186
|
|
|
} |
187
|
|
|
|
188
|
4 |
|
$variables = is_array($variables) ? $variables : []; |
189
|
|
|
|
190
|
4 |
|
$this->addRecipient('bcc', $address, $variables); |
191
|
|
|
|
192
|
4 |
|
return end($this->message['bcc']); |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* @param string $address |
197
|
|
|
* @param array|null $variables |
198
|
|
|
* |
199
|
|
|
* @return mixed |
200
|
|
|
*/ |
201
|
7 |
View Code Duplication |
public function setFromAddress($address, $variables = null) |
|
|
|
|
202
|
|
|
{ |
203
|
7 |
|
$variables = is_array($variables) ? $variables : []; |
204
|
|
|
|
205
|
7 |
|
$this->addRecipient('from', $address, $variables); |
206
|
|
|
|
207
|
7 |
|
return $this->message['from']; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* @param string $address |
212
|
|
|
* @param array|null $variables |
213
|
|
|
* |
214
|
|
|
* @return mixed |
215
|
|
|
*/ |
216
|
1 |
View Code Duplication |
public function setReplyToAddress($address, $variables = null) |
|
|
|
|
217
|
|
|
{ |
218
|
1 |
|
$variables = is_array($variables) ? $variables : []; |
219
|
|
|
|
220
|
1 |
|
$this->addRecipient('h:reply-to', $address, $variables); |
221
|
|
|
|
222
|
1 |
|
return $this->message['h:reply-to']; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* @param string $subject |
227
|
|
|
* |
228
|
|
|
* @return mixed |
229
|
|
|
*/ |
230
|
7 |
|
public function setSubject($subject = '') |
231
|
|
|
{ |
232
|
7 |
|
if ($subject == null || $subject == '') { |
233
|
|
|
$subject = ' '; |
234
|
|
|
} |
235
|
7 |
|
$this->message['subject'] = $subject; |
236
|
|
|
|
237
|
7 |
|
return $this->message['subject']; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* @param string $headerName |
242
|
|
|
* @param mixed $headerData |
243
|
|
|
* |
244
|
|
|
* @return mixed |
245
|
|
|
*/ |
246
|
3 |
|
public function addCustomHeader($headerName, $headerData) |
247
|
|
|
{ |
248
|
3 |
|
if (!preg_match('/^h:/i', $headerName)) { |
249
|
3 |
|
$headerName = 'h:'.$headerName; |
250
|
3 |
|
} |
251
|
|
|
|
252
|
3 |
|
if (array_key_exists($headerName, $this->message)) { |
253
|
2 |
|
if (is_array($this->message[$headerName])) { |
254
|
|
|
$this->message[$headerName][] = $headerData; |
255
|
|
|
} else { |
256
|
2 |
|
$this->message[$headerName] = [$this->message[$headerName], $headerData]; |
257
|
|
|
} |
258
|
2 |
|
} else { |
259
|
3 |
|
$this->message[$headerName] = $headerData; |
260
|
|
|
} |
261
|
|
|
|
262
|
3 |
|
return $this->message[$headerName]; |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
/** |
266
|
|
|
* @param string $textBody |
267
|
|
|
* |
268
|
|
|
* @return string |
269
|
|
|
*/ |
270
|
7 |
|
public function setTextBody($textBody) |
271
|
|
|
{ |
272
|
7 |
|
if ($textBody == null || $textBody == '') { |
273
|
|
|
$textBody = ' '; |
274
|
|
|
} |
275
|
7 |
|
$this->message['text'] = $textBody; |
276
|
|
|
|
277
|
7 |
|
return $this->message['text']; |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* @param string $htmlBody |
282
|
|
|
* |
283
|
|
|
* @return string |
284
|
|
|
*/ |
285
|
1 |
|
public function setHtmlBody($htmlBody) |
286
|
|
|
{ |
287
|
1 |
|
if ($htmlBody == null || $htmlBody == '') { |
288
|
|
|
$htmlBody = ' '; |
289
|
|
|
} |
290
|
1 |
|
$this->message['html'] = $htmlBody; |
291
|
|
|
|
292
|
1 |
|
return $this->message['html']; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* @param string $attachmentPath |
297
|
|
|
* @param string|null $attachmentName |
298
|
|
|
* |
299
|
|
|
* @return bool |
300
|
|
|
*/ |
301
|
3 |
|
public function addAttachment($attachmentPath, $attachmentName = null) |
302
|
|
|
{ |
303
|
3 |
|
if (isset($this->files['attachment'])) { |
304
|
|
|
$attachment = [ |
305
|
3 |
|
'filePath' => $attachmentPath, |
306
|
3 |
|
'remoteName' => $attachmentName, |
307
|
3 |
|
]; |
308
|
3 |
|
array_push($this->files['attachment'], $attachment); |
309
|
3 |
|
} else { |
310
|
3 |
|
$this->files['attachment'] = [ |
311
|
|
|
[ |
312
|
3 |
|
'filePath' => $attachmentPath, |
313
|
3 |
|
'remoteName' => $attachmentName, |
314
|
3 |
|
], |
315
|
|
|
]; |
316
|
|
|
} |
317
|
|
|
|
318
|
3 |
|
return true; |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
/** |
322
|
|
|
* @param string $inlineImagePath |
323
|
|
|
* @param string|null $inlineImageName |
324
|
|
|
* |
325
|
|
|
* @throws InvalidParameter |
326
|
|
|
* |
327
|
|
|
* @return bool |
328
|
|
|
*/ |
329
|
4 |
|
public function addInlineImage($inlineImagePath, $inlineImageName = null) |
330
|
|
|
{ |
331
|
4 |
|
if (strpos($inlineImagePath, '@') !== 0) { |
332
|
|
|
throw new InvalidParameter(ExceptionMessages::INVALID_PARAMETER_INLINE); |
333
|
|
|
} |
334
|
|
|
|
335
|
4 |
|
$this->files['inline'][] = [ |
336
|
4 |
|
'filePath' => $inlineImagePath, |
337
|
4 |
|
'remoteName' => $inlineImageName, |
338
|
|
|
]; |
339
|
|
|
|
340
|
4 |
|
return true; |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
/** |
344
|
|
|
* @param bool $testMode |
345
|
|
|
* |
346
|
|
|
* @return string |
347
|
|
|
*/ |
348
|
1 |
View Code Duplication |
public function setTestMode($testMode) |
|
|
|
|
349
|
|
|
{ |
350
|
1 |
|
if (filter_var($testMode, FILTER_VALIDATE_BOOLEAN)) { |
351
|
1 |
|
$testMode = 'yes'; |
352
|
1 |
|
} else { |
353
|
1 |
|
$testMode = 'no'; |
354
|
|
|
} |
355
|
1 |
|
$this->message['o:testmode'] = $testMode; |
356
|
|
|
|
357
|
1 |
|
return $this->message['o:testmode']; |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
/** |
361
|
|
|
* @param string|int $campaignId |
362
|
|
|
* |
363
|
|
|
* @throws TooManyParameters |
364
|
|
|
* |
365
|
|
|
* @return string|int |
366
|
|
|
*/ |
367
|
1 |
View Code Duplication |
public function addCampaignId($campaignId) |
|
|
|
|
368
|
|
|
{ |
369
|
1 |
|
if ($this->counters['attributes']['campaign_id'] < Api::CAMPAIGN_ID_LIMIT) { |
370
|
1 |
|
if (isset($this->message['o:campaign'])) { |
371
|
1 |
|
array_push($this->message['o:campaign'], $campaignId); |
372
|
1 |
|
} else { |
373
|
1 |
|
$this->message['o:campaign'] = [$campaignId]; |
374
|
|
|
} |
375
|
1 |
|
$this->counters['attributes']['campaign_id'] += 1; |
376
|
|
|
|
377
|
1 |
|
return $this->message['o:campaign']; |
378
|
|
|
} else { |
379
|
|
|
throw new TooManyParameters(ExceptionMessages::TOO_MANY_PARAMETERS_CAMPAIGNS); |
380
|
|
|
} |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
/** |
384
|
|
|
* @param string $tag |
385
|
|
|
* |
386
|
|
|
* @throws TooManyParameters |
387
|
|
|
*/ |
388
|
|
View Code Duplication |
public function addTag($tag) |
|
|
|
|
389
|
|
|
{ |
390
|
|
|
if ($this->counters['attributes']['tag'] < Api::TAG_LIMIT) { |
391
|
|
|
if (isset($this->message['o:tag'])) { |
392
|
|
|
array_push($this->message['o:tag'], $tag); |
393
|
|
|
} else { |
394
|
|
|
$this->message['o:tag'] = [$tag]; |
395
|
|
|
} |
396
|
|
|
$this->counters['attributes']['tag'] += 1; |
397
|
|
|
|
398
|
|
|
return $this->message['o:tag']; |
399
|
|
|
} else { |
400
|
|
|
throw new TooManyParameters(ExceptionMessages::TOO_MANY_PARAMETERS_TAGS); |
401
|
|
|
} |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
/** |
405
|
|
|
* @param bool $enabled |
406
|
|
|
* |
407
|
|
|
* @return mixed |
408
|
|
|
*/ |
409
|
1 |
View Code Duplication |
public function setDkim($enabled) |
|
|
|
|
410
|
|
|
{ |
411
|
1 |
|
if (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) { |
412
|
1 |
|
$enabled = 'yes'; |
413
|
1 |
|
} else { |
414
|
1 |
|
$enabled = 'no'; |
415
|
|
|
} |
416
|
1 |
|
$this->message['o:dkim'] = $enabled; |
417
|
|
|
|
418
|
1 |
|
return $this->message['o:dkim']; |
419
|
|
|
} |
420
|
|
|
|
421
|
|
|
/** |
422
|
|
|
* @param bool $enabled |
423
|
|
|
* |
424
|
|
|
* @return string |
425
|
|
|
*/ |
426
|
1 |
View Code Duplication |
public function setOpenTracking($enabled) |
|
|
|
|
427
|
|
|
{ |
428
|
1 |
|
if (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) { |
429
|
1 |
|
$enabled = 'yes'; |
430
|
1 |
|
} else { |
431
|
1 |
|
$enabled = 'no'; |
432
|
|
|
} |
433
|
1 |
|
$this->message['o:tracking-opens'] = $enabled; |
434
|
|
|
|
435
|
1 |
|
return $this->message['o:tracking-opens']; |
436
|
|
|
} |
437
|
|
|
|
438
|
|
|
/** |
439
|
|
|
* @param bool $enabled |
440
|
|
|
* |
441
|
|
|
* @return string |
442
|
|
|
*/ |
443
|
1 |
|
public function setClickTracking($enabled) |
444
|
|
|
{ |
445
|
1 |
|
if (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) { |
446
|
1 |
|
$enabled = 'yes'; |
447
|
1 |
|
} elseif ($enabled == 'html') { |
448
|
|
|
$enabled = 'html'; |
449
|
|
|
} else { |
450
|
1 |
|
$enabled = 'no'; |
451
|
|
|
} |
452
|
1 |
|
$this->message['o:tracking-clicks'] = $enabled; |
453
|
|
|
|
454
|
1 |
|
return $this->message['o:tracking-clicks']; |
455
|
|
|
} |
456
|
|
|
|
457
|
|
|
/** |
458
|
|
|
* @param string $timeDate |
459
|
|
|
* @param string|null $timeZone |
460
|
|
|
* |
461
|
|
|
* @return string |
462
|
|
|
*/ |
463
|
1 |
|
public function setDeliveryTime($timeDate, $timeZone = null) |
464
|
|
|
{ |
465
|
1 |
|
if (isset($timeZone)) { |
466
|
1 |
|
$timeZoneObj = new \DateTimeZone("$timeZone"); |
467
|
1 |
|
} else { |
468
|
1 |
|
$timeZoneObj = new \DateTimeZone(Api::DEFAULT_TIME_ZONE); |
469
|
|
|
} |
470
|
|
|
|
471
|
1 |
|
$dateTimeObj = new \DateTime($timeDate, $timeZoneObj); |
472
|
1 |
|
$formattedTimeDate = $dateTimeObj->format(\DateTime::RFC2822); |
473
|
1 |
|
$this->message['o:deliverytime'] = $formattedTimeDate; |
474
|
|
|
|
475
|
1 |
|
return $this->message['o:deliverytime']; |
476
|
|
|
} |
477
|
|
|
|
478
|
|
|
/** |
479
|
|
|
* @param string $customName |
480
|
|
|
* @param mixed $data |
481
|
|
|
*/ |
482
|
1 |
|
public function addCustomData($customName, $data) |
483
|
|
|
{ |
484
|
1 |
|
$this->message['v:'.$customName] = json_encode($data); |
485
|
1 |
|
} |
486
|
|
|
|
487
|
|
|
/** |
488
|
|
|
* @param string $parameterName |
489
|
|
|
* @param mixed $data |
490
|
|
|
* |
491
|
|
|
* @return mixed |
492
|
|
|
*/ |
493
|
2 |
|
public function addCustomParameter($parameterName, $data) |
494
|
|
|
{ |
495
|
2 |
|
if (isset($this->message[$parameterName])) { |
496
|
1 |
|
array_push($this->message[$parameterName], $data); |
497
|
|
|
|
498
|
1 |
|
return $this->message[$parameterName]; |
499
|
|
|
} else { |
500
|
2 |
|
$this->message[$parameterName] = [$data]; |
501
|
|
|
|
502
|
2 |
|
return $this->message[$parameterName]; |
503
|
|
|
} |
504
|
|
|
} |
505
|
|
|
|
506
|
|
|
/** |
507
|
|
|
* @param array $message |
508
|
|
|
*/ |
509
|
1 |
|
public function setMessage($message) |
510
|
|
|
{ |
511
|
1 |
|
$this->message = $message; |
512
|
1 |
|
} |
513
|
|
|
|
514
|
|
|
/** |
515
|
|
|
* @return array |
516
|
|
|
*/ |
517
|
31 |
|
public function getMessage() |
518
|
|
|
{ |
519
|
31 |
|
return $this->message; |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
/** |
523
|
|
|
* @return array |
524
|
|
|
*/ |
525
|
6 |
|
public function getFiles() |
526
|
|
|
{ |
527
|
6 |
|
return $this->files; |
528
|
|
|
} |
529
|
|
|
} |
530
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.