28 | * @copyright 2009 - 2017 Eoghan O'Brien
29 | * @license http://github.com/eoghanobrien/php-simple-mail/LICENCE.txt MIT
30 | * @version 1.7.1
31 | * @link http://github.com/eoghanobrien/php-simple-mail
32 | */
33 | class SimpleMail
34 | {
35 | /**
36 | * @var int $_wrap
37 | */
38 | protected $_wrap = 78;
39 |
40 | /**
41 | * @var array $_to
42 | */
43 | protected $_to = array();
44 |
45 | /**
46 | * @var string $_subject
47 | */
48 | protected $_subject;
49 |
50 | /**
51 | * @var string $_message
52 | */
53 | protected $_message;
54 |
55 | /**
56 | * @var array $_headers
57 | */
58 | protected $_headers = array();
59 |
60 | /**
61 | * @var string $_parameters
62 | */
63 | protected $_params;
64 |
65 | /**
66 | * @var array $_attachments
67 | */
68 | protected $_attachments = array();
69 |
70 | /**
71 | * @var string $_uid
72 | */
73 | protected $_uid;
74 |
75 | /**
76 | * Named constructor.
77 | *
78 | * @return static
79 | */
80 | public static function make()
81 | {
82 | return new SimpleMail();
83 | }
84 |
85 | /**
86 | * __construct
87 | *
88 | * Resets the class properties.
89 | */
90 | public function __construct()
91 | {
92 | $this->reset();
93 | }
94 |
95 | /**
96 | * reset
97 | *
98 | * Resets all properties to initial state.
99 | *
100 | * @return self
101 | */
102 | public function reset()
103 | {
104 | $this->_to = array();
105 | $this->_headers = array();
106 | $this->_subject = null;
107 | $this->_message = null;
108 | $this->_wrap = 78;
109 | $this->_params = null;
110 | $this->_attachments = array();
111 | $this->_uid = $this->getUniqueId();
112 | return $this;
113 | }
114 |
115 | /**
116 | * setTo
117 | *
118 | * @param string $email The email address to send to.
119 | * @param string $name The name of the person to send to.
120 | *
121 | * @return self
122 | */
123 | public function setTo($email, $name)
124 | {
125 | $this->_to[] = $this->formatHeader((string) $email, (string) $name);
126 | return $this;
127 | }
128 |
129 | /**
130 | * getTo
131 | *
132 | * Return an array of formatted To addresses.
133 | *
134 | * @return array
135 | */
136 | public function getTo()
137 | {
138 | return $this->_to;
139 | }
140 |
141 | /**
142 | * setFrom
143 | *
144 | * @param string $email The email to send as from.
145 | * @param string $name The name to send as from.
146 | *
147 | * @return self
148 | */
149 | public function setFrom($email, $name)
150 | {
151 | $this->addMailHeader('From', (string) $email, (string) $name);
152 | return $this;
153 | }
154 |
155 | /**
156 | * setCc
157 | *
158 | * @param array $pairs An array of name => email pairs.
159 | *
160 | * @return self
161 | */
162 | public function setCc(array $pairs)
163 | {
164 | return $this->addMailHeaders('Cc', $pairs);
165 | }
166 |
167 | /**
168 | * setBcc
169 | *
170 | * @param array $pairs An array of name => email pairs.
171 | *
172 | * @return self
173 | */
174 | public function setBcc(array $pairs)
175 | {
176 | return $this->addMailHeaders('Bcc', $pairs);
177 | }
178 |
179 | /**
180 | * setReplyTo
181 | *
182 | * @param string $email
183 | * @param string $name
184 | *
185 | * @return self
186 | */
187 | public function setReplyTo($email, $name = null)
188 | {
189 | return $this->addMailHeader('Reply-To', $email, $name);
190 | }
191 |
192 | /**
193 | * setHtml
194 | *
195 | * @return self
196 | */
197 | public function setHtml()
198 | {
199 | return $this->addGenericHeader(
200 | 'Content-Type', 'text/html; charset="utf-8"'
201 | );
202 | }
203 |
204 | /**
205 | * setSubject
206 | *
207 | * @param string $subject The email subject
208 | *
209 | * @return self
210 | */
211 | public function setSubject($subject)
212 | {
213 | $this->_subject = $this->encodeUtf8(
214 | $this->filterOther((string) $subject)
215 | );
216 | return $this;
217 | }
218 |
219 | /**
220 | * getSubject function.
221 | *
222 | * @return string
223 | */
224 | public function getSubject()
225 | {
226 | return $this->_subject;
227 | }
228 |
229 | /**
230 | * setMessage
231 | *
232 | * @param string $message The message to send.
233 | *
234 | * @return self
235 | */
236 | public function setMessage($message)
237 | {
238 | $this->_message = str_replace("\n.", "\n..", (string) $message);
239 | return $this;
240 | }
241 |
242 | /**
243 | * getMessage
244 | *
245 | * @return string
246 | */
247 | public function getMessage()
248 | {
249 | return $this->_message;
250 | }
251 |
252 | /**
253 | * addAttachment
254 | *
255 | * @param string $path The file path to the attachment.
256 | * @param string $filename The filename of the attachment when emailed.
257 | * @param null $data
258 | *
259 | * @return self
260 | */
261 | public function addAttachment($path, $filename = null, $data = null)
262 | {
263 | $filename = empty($filename) ? basename($path) : $filename;
264 | $filename = $this->encodeUtf8($this->filterOther((string) $filename));
265 | $data = empty($data) ? $this->getAttachmentData($path) : $data;
266 | $this->_attachments[] = array(
267 | 'path' => $path,
268 | 'file' => $filename,
269 | 'data' => chunk_split(base64_encode($data))
270 | );
271 | return $this;
272 | }
273 |
274 | /**
275 | * getAttachmentData
276 | *
277 | * @param string $path The path to the attachment file.
278 | *
279 | * @return string
280 | */
281 | public function getAttachmentData($path)
282 | {
283 | $filesize = filesize($path);
284 | $handle = fopen($path, "r");
285 | $attachment = fread($handle, $filesize);
286 | fclose($handle);
287 | return $attachment;
288 | }
289 |
290 | /**
291 | * addMailHeader
292 | *
293 | * @param string $header The header to add.
294 | * @param string $email The email to add.
295 | * @param string $name The name to add.
296 | *
297 | * @return self
298 | */
299 | public function addMailHeader($header, $email, $name = null)
300 | {
301 | $address = $this->formatHeader((string) $email, (string) $name);
302 | $this->_headers[] = sprintf('%s: %s', (string) $header, $address);
303 | return $this;
304 | }
305 |
306 | /**
307 | * addMailHeaders
308 | *
309 | * @param string $header The header to add.
310 | * @param array $pairs An array of name => email pairs.
311 | *
312 | * @return self
313 | */
314 | public function addMailHeaders($header, array $pairs)
315 | {
316 | if (count($pairs) === 0) {
317 | throw new InvalidArgumentException(
318 | 'You must pass at least one name => email pair.'
319 | );
320 | }
321 | $addresses = array();
322 | foreach ($pairs as $name => $email) {
323 | $name = is_numeric($name) ? null : $name;
324 | $addresses[] = $this->formatHeader($email, $name);
325 | }
326 | $this->addGenericHeader($header, implode(',', $addresses));
327 | return $this;
328 | }
329 |
330 | /**
331 | * addGenericHeader
332 | *
333 | * @param string $header The generic header to add.
334 | * @param mixed $value The value of the header.
335 | *
336 | * @return self
337 | */
338 | public function addGenericHeader($header, $value)
339 | {
340 | $this->_headers[] = sprintf(
341 | '%s: %s',
342 | (string) $header,
343 | (string) $value
344 | );
345 | return $this;
346 | }
347 |
348 | /**
349 | * getHeaders
350 | *
351 | * Return the headers registered so far as an array.
352 | *
353 | * @return array
354 | */
355 | public function getHeaders()
356 | {
357 | return $this->_headers;
358 | }
359 |
360 | /**
361 | * setAdditionalParameters
362 | *
363 | * Such as "-fyouremail@yourserver.com
364 | *
365 | * @param string $additionalParameters The addition mail parameter.
366 | *
367 | * @return self
368 | */
369 | public function setParameters($additionalParameters)
370 | {
371 | $this->_params = (string) $additionalParameters;
372 | return $this;
373 | }
374 |
375 | /**
376 | * getAdditionalParameters
377 | *
378 | * @return string
379 | */
380 | public function getParameters()
381 | {
382 | return $this->_params;
383 | }
384 |
385 | /**
386 | * setWrap
387 | *
388 | * @param int $wrap The number of characters at which the message will wrap.
389 | *
390 | * @return self
391 | */
392 | public function setWrap($wrap = 78)
393 | {
394 | $wrap = (int) $wrap;
395 | if ($wrap < 1) {
396 | $wrap = 78;
397 | }
398 | $this->_wrap = $wrap;
399 | return $this;
400 | }
401 |
402 | /**
403 | * getWrap
404 | *
405 | * @return int
406 | */
407 | public function getWrap()
408 | {
409 | return $this->_wrap;
410 | }
411 |
412 | /**
413 | * hasAttachments
414 | *
415 | * Checks if the email has any registered attachments.
416 | *
417 | * @return bool
418 | */
419 | public function hasAttachments()
420 | {
421 | return !empty($this->_attachments);
422 | }
423 |
424 | /**
425 | * assembleAttachment
426 | *
427 | * @return string
428 | */
429 | public function assembleAttachmentHeaders()
430 | {
431 | $head = array();
432 | $head[] = "MIME-Version: 1.0";
433 | $head[] = "Content-Type: multipart/mixed; boundary=\"{$this->_uid}\"";
434 |
435 | return join(PHP_EOL, $head);
436 | }
437 |
438 | /**
439 | * assembleAttachmentBody
440 | *
441 | * @return string
442 | */
443 | public function assembleAttachmentBody()
444 | {
445 | $body = array();
446 | $body[] = "This is a multi-part message in MIME format.";
447 | $body[] = "--{$this->_uid}";
448 | $body[] = "Content-Type: text/html; charset=\"utf-8\"";
449 | $body[] = "Content-Transfer-Encoding: quoted-printable";
450 | $body[] = "";
451 | $body[] = quoted_printable_encode($this->_message);
452 | $body[] = "";
453 | $body[] = "--{$this->_uid}";
454 |
455 | foreach ($this->_attachments as $attachment) {
456 | $body[] = $this->getAttachmentMimeTemplate($attachment);
457 | }
458 |
459 | return implode(PHP_EOL, $body) . '--';
460 | }
461 |
462 | /**
463 | * getAttachmentMimeTemplate
464 | *
465 | * @param array $attachment An array containing 'file' and 'data' keys.
466 | *
467 | * @return string
468 | */
469 | public function getAttachmentMimeTemplate($attachment)
470 | {
471 | $file = $attachment['file'];
472 | $data = $attachment['data'];
473 |
474 | $head = array();
475 | $head[] = "Content-Type: application/octet-stream; name=\"{$file}\"";
476 | $head[] = "Content-Transfer-Encoding: base64";
477 | $head[] = "Content-Disposition: attachment; filename=\"{$file}\"";
478 | $head[] = "";
479 | $head[] = $data;
480 | $head[] = "";
481 | $head[] = "--{$this->_uid}";
482 |
483 | return implode(PHP_EOL, $head);
484 | }
485 |
486 | /**
487 | * send
488 | *
489 | * @return boolean
490 | * @throws \RuntimeException on no 'To: ' address to send to.
491 | */
492 | public function send()
493 | {
494 | $to = $this->getToForSend();
495 | $headers = $this->getHeadersForSend();
496 |
497 | if (empty($to)) {
498 | throw new \RuntimeException(
499 | 'Unable to send, no To address has been set.'
500 | );
501 | }
502 |
503 | if ($this->hasAttachments()) {
504 | $message = $this->assembleAttachmentBody();
505 | $headers .= PHP_EOL . $this->assembleAttachmentHeaders();
506 | } else {
507 | $message = $this->getWrapMessage();
508 | }
509 |
510 | return mail($to, $this->_subject, $message, $headers, $this->_params);
511 | }
512 |
513 | /**
514 | * debug
515 | *
516 | * @return string
517 | */
518 | public function debug()
519 | {
520 | return '' . print_r($this, true) . '
';
521 | }
522 |
523 | /**
524 | * magic __toString function
525 | *
526 | * @return string
527 | */
528 | public function __toString()
529 | {
530 | return print_r($this, true);
531 | }
532 |
533 | /**
534 | * formatHeader
535 | *
536 | * Formats a display address for emails according to RFC2822 e.g.
537 | * Name
538 | *
539 | * @param string $email The email address.
540 | * @param string $name The display name.
541 | *
542 | * @return string
543 | */
544 | public function formatHeader($email, $name = null)
545 | {
546 | $email = $this->filterEmail((string) $email);
547 | if (empty($name)) {
548 | return $email;
549 | }
550 | $name = $this->encodeUtf8($this->filterName((string) $name));
551 | return sprintf('"%s" <%s>', $name, $email);
552 | }
553 |
554 | /**
555 | * encodeUtf8
556 | *
557 | * @param string $value The value to encode.
558 | *
559 | * @return string
560 | */
561 | public function encodeUtf8($value)
562 | {
563 | $value = trim($value);
564 | if (preg_match('/(\s)/', $value)) {
565 | return $this->encodeUtf8Words($value);
566 | }
567 | return $this->encodeUtf8Word($value);
568 | }
569 |
570 | /**
571 | * encodeUtf8Word
572 | *
573 | * @param string $value The word to encode.
574 | *
575 | * @return string
576 | */
577 | public function encodeUtf8Word($value)
578 | {
579 | return sprintf('=?UTF-8?B?%s?=', base64_encode($value));
580 | }
581 |
582 | /**
583 | * encodeUtf8Words
584 | *
585 | * @param string $value The words to encode.
586 | *
587 | * @return string
588 | */
589 | public function encodeUtf8Words($value)
590 | {
591 | $words = explode(' ', $value);
592 | $encoded = array();
593 | foreach ($words as $word) {
594 | $encoded[] = $this->encodeUtf8Word($word);
595 | }
596 | return join($this->encodeUtf8Word(' '), $encoded);
597 | }
598 |
599 | /**
600 | * filterEmail
601 | *
602 | * Removes any carriage return, line feed, tab, double quote, comma
603 | * and angle bracket characters before sanitizing the email address.
604 | *
605 | * @param string $email The email to filter.
606 | *
607 | * @return string
608 | */
609 | public function filterEmail($email)
610 | {
611 | $rule = array(
612 | "\r" => '',
613 | "\n" => '',
614 | "\t" => '',
615 | '"' => '',
616 | ',' => '',
617 | '<' => '',
618 | '>' => ''
619 | );
620 | $email = strtr($email, $rule);
621 | $email = filter_var($email, FILTER_SANITIZE_EMAIL);
622 | return $email;
623 | }
624 |
625 | /**
626 | * filterName
627 | *
628 | * Removes any carriage return, line feed or tab characters. Replaces
629 | * double quotes with single quotes and angle brackets with square
630 | * brackets, before sanitizing the string and stripping out html tags.
631 | *
632 | * @param string $name The name to filter.
633 | *
634 | * @return string
635 | */
636 | public function filterName($name)
637 | {
638 | $rule = array(
639 | "\r" => '',
640 | "\n" => '',
641 | "\t" => '',
642 | '"' => "'",
643 | '<' => '[',
644 | '>' => ']',
645 | );
646 | $filtered = filter_var(
647 | $name,
648 | FILTER_SANITIZE_STRING,
649 | FILTER_FLAG_NO_ENCODE_QUOTES
650 | );
651 | return trim(strtr($filtered, $rule));
652 | }
653 |
654 | /**
655 | * filterOther
656 | *
657 | * Removes ASCII control characters including any carriage return, line
658 | * feed or tab characters.
659 | *
660 | * @param string $data The data to filter.
661 | *
662 | * @return string
663 | */
664 | public function filterOther($data)
665 | {
666 | return filter_var($data, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW);
667 | }
668 |
669 | /**
670 | * getHeadersForSend
671 | *
672 | * @return string
673 | */
674 | public function getHeadersForSend()
675 | {
676 | if (empty($this->_headers)) {
677 | return '';
678 | }
679 | return join(PHP_EOL, $this->_headers);
680 | }
681 |
682 | /**
683 | * getToForSend
684 | *
685 | * @return string
686 | */
687 | public function getToForSend()
688 | {
689 | if (empty($this->_to)) {
690 | return '';
691 | }
692 | return join(', ', $this->_to);
693 | }
694 |
695 | /**
696 | * getUniqueId
697 | *
698 | * @return string
699 | */
700 | public function getUniqueId()
701 | {
702 | return md5(uniqid(time()));
703 | }
704 |
705 | /**
706 | * getWrapMessage
707 | *
708 | * @return string
709 | */
710 | public function getWrapMessage()
711 | {
712 | return wordwrap($this->_message, $this->_wrap);
713 | }
714 | }
715 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eoghanobrien/php-simple-mail",
3 | "type": "library",
4 | "description": "Provides a simple, chainable wrapper for creating and sending emails using the PHP mail() function.",
5 | "keywords": ["email","php5"],
6 | "homepage": "https://github.com/eoghanobrien/php-simple-mail",
7 | "license": "MIT",
8 | "authors": [
9 | {
10 | "name": "Eoghan O'Brien",
11 | "email": "eoghan@eoghanobrien.com",
12 | "homepage": "http://www.eoghanobrien.com",
13 | "role": "Developer"
14 | }
15 | ],
16 | "require": {
17 | "php": ">=5.2.0"
18 | },
19 | "require-dev": {
20 | "phpunit/phpunit": "~4.8",
21 | "squizlabs/php_codesniffer": "~2.8"
22 | },
23 | "autoload": {
24 | "classmap": ["class.simple_mail.php"]
25 | },
26 | "scripts": {
27 | "test-build": [
28 | "vendor/bin/phpunit --colors=always",
29 | "vendor/bin/phpcs --standard=Zend class.simple_mail.php",
30 | "php -l class.simple_mail.php"
31 | ]
32 | }
33 | }
--------------------------------------------------------------------------------
/example/example.php:
--------------------------------------------------------------------------------
1 | Simple Mail';
4 |
5 | /* @var SimpleMail $mail */
6 | $mail = SimpleMail::make()
7 | ->setTo('test1@example.com', 'Recipient 1')
8 | ->setSubject("Hi Amy O'Neill, Welcome!")
9 | ->setFrom('sender@gmail.com', 'Mail Bot')
10 | ->setReplyTo('reply@test.com', 'Mail Bot')
11 | ->setCc(['Recipient 2' => 'test2@example.com', 'Recipient 3' => 'test3@example.com'])
12 | ->setBcc(['Recipient 4' => 'test4@example.com'])
13 | ->addGenericHeader('X-Mailer', 'PHP/' . phpversion())
14 | ->setHtml()
15 | ->setMessage('This is a test message.')
16 | ->setWrap(78);
17 | $send = $mail->send();
18 | //echo $mail->debug();
19 |
20 | if ($send) {
21 | echo 'Email was sent successfully!';
22 | } else {
23 | echo 'An error occurred. We could not send email';
24 | }
25 |
--------------------------------------------------------------------------------
/example/example_attachment.php:
--------------------------------------------------------------------------------
1 | Simple Mail';
4 |
5 | /* @var SimpleMail $mail */
6 | $mail = new SimpleMail();
7 | $mail->setTo('test1@example.com', 'Recipient 1')
8 | ->setSubject('Testing multiple attachments!')
9 | ->setFrom('sender@gmail.com', 'Mail Bot')
10 | ->setReplyTo('reply@test.com', 'Mail Bot')
11 | ->setCc(['Recipient 2' => 'test2@example.com', 'Recipient 3' => 'test3@example.com'])
12 | ->setBcc(['Recipient 4' => 'test4@example.com'])
13 | ->addAttachment(__DIR__ . '/pbXBsZSwgY2hh.jpg', 'lolcat_finally_arrived.jpg')
14 | ->addAttachment(__DIR__ . '/lolcat_what.jpg')
15 | ->setHtml()
16 | ->setMessage('This is a test message.')
17 | ->setWrap(100);
18 |
19 | $send = $mail->send();
20 | //$mailer->debug();
21 |
22 | if ($send) {
23 | echo 'Email sent successfully';
24 | } else {
25 | echo 'Could not send email';
26 | }
27 |
--------------------------------------------------------------------------------
/example/example_attachment_textfile.php:
--------------------------------------------------------------------------------
1 | Simple Mail';
4 |
5 | /* @var SimpleMail $mail */
6 | $mail = new SimpleMail();
7 | $mail->setTo('not_a_real_email@gmail.com', "Raphaëlle Agogué")
8 | ->setFrom('not_a_real_email@gmail.com', 'Jack Sprat')
9 | ->setSubject('This is a test message')
10 | ->addAttachment('test.txt')
11 | ->setMessage('HALLO');
12 | $send = $mail->send();
13 | //echo $mail->debug();
14 |
15 | if ($send) {
16 | echo 'Email sent successfully';
17 | }
18 | else {
19 | echo 'Could not send email';
20 | }
21 |
--------------------------------------------------------------------------------
/example/lolcat_what.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eoghanobrien/php-simple-mail/4f1b6f969811a7adf48b6cdb428ea5ced8115691/example/lolcat_what.jpg
--------------------------------------------------------------------------------
/example/pbXBsZSwgY2hh.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eoghanobrien/php-simple-mail/4f1b6f969811a7adf48b6cdb428ea5ced8115691/example/pbXBsZSwgY2hh.jpg
--------------------------------------------------------------------------------
/example/test.txt:
--------------------------------------------------------------------------------
1 | Testing attachments
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ./tests
5 |
6 |
7 |
8 |
9 | class.simple_mail.php
10 |
11 |
12 |
13 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/class.simple_mail.test.php:
--------------------------------------------------------------------------------
1 | name = 'Tester';
25 | $this->email = 'test@gmail.com';
26 | $this->mailer = new SimpleMail();
27 | $this->directory = realpath('./');
28 | }
29 |
30 | /**
31 | * @test
32 | */
33 | public function it_can_be_constructed_via_named_static_method()
34 | {
35 | $this->assertInstanceOf('SimpleMail', SimpleMail::make());
36 | }
37 |
38 | /**
39 | * @test
40 | */
41 | public function it_will_set_expected_values_for_setTo()
42 | {
43 | $this->mailer->setTo($this->email, $this->name);
44 |
45 | $expected = sprintf('"%s" <%s>', $this->mailer->encodeUtf8($this->name), $this->email);
46 |
47 | $this->assertContains($expected, $this->mailer->getTo());
48 | }
49 |
50 | /**
51 | * @test
52 | */
53 | public function it_will_set_expected_header_for_setTo()
54 | {
55 | $this->mailer->setTo($this->email, $this->name);
56 | $header = $this->mailer->formatHeader($this->email, $this->name);
57 |
58 | $this->assertContains($header, $this->mailer->getTo());
59 | }
60 |
61 | /**
62 | * @test
63 | */
64 | public function it_will_set_expected_header_for_setSubject()
65 | {
66 | $this->mailer->setSubject('Testing Simple Mail');
67 |
68 | $this->assertSame($this->mailer->encodeUtf8('Testing Simple Mail'), $this->mailer->getSubject());
69 | }
70 |
71 | /**
72 | * @test
73 | */
74 | public function it_can_correctly_utf8_encode_words()
75 | {
76 | $expected = sprintf('=?UTF-8?B?%s?=', base64_encode('Test'));
77 | $encoded = $this->mailer->encodeUtf8('Test');
78 |
79 | $this->assertSame($expected, $encoded);
80 | }
81 |
82 | /**
83 | * @test
84 | */
85 | public function it_returns_the_correct_words_when_using_encodeUtf8()
86 | {
87 | $space = sprintf('=?UTF-8?B?%s?=', base64_encode(' '));
88 | $expected = array(
89 | sprintf('=?UTF-8?B?%s?=', base64_encode('Testing')),
90 | sprintf('=?UTF-8?B?%s?=', base64_encode('Multiple')),
91 | sprintf('=?UTF-8?B?%s?=', base64_encode('Words'))
92 | );
93 | $encoded = $this->mailer->encodeUtf8('Testing Multiple Words');
94 |
95 | $this->assertSame(implode($space, $expected), $encoded);
96 | }
97 |
98 | /**
99 | * @test
100 | */
101 | public function it_will_set_expected_message()
102 | {
103 | $this->mailer->setMessage('Testing Simple Mail');
104 |
105 | $this->assertSame($this->mailer->getMessage(), 'Testing Simple Mail');
106 | }
107 |
108 | /**
109 | * @test
110 | */
111 | public function it_sets_the_expected_header_for_carbon_copy()
112 | {
113 | $this->mailer->setCc(array($this->name => $this->email));
114 | $header = sprintf('%s: %s', 'Cc', $this->mailer->formatHeader($this->email, $this->name));
115 |
116 | $this->assertContains($header, $this->mailer->getHeaders());
117 | }
118 |
119 | /**
120 | * @test
121 | */
122 | public function it_sets_the_expected_header_for_blind_carbon_copy()
123 | {
124 | $this->mailer->setBcc(array('Tester' => 'test@gmail.com'));
125 | $header = sprintf('%s: %s', 'Bcc', $this->mailer->formatHeader($this->email, $this->name));
126 |
127 | $this->assertContains($header, $this->mailer->getHeaders());
128 | }
129 |
130 | /**
131 | * @test
132 | */
133 | public function it_sets_the_expected_header_for_html_content_type()
134 | {
135 | $this->mailer->setHtml();
136 |
137 | $this->assertContains('Content-Type: text/html; charset="utf-8"', $this->mailer->getHeaders());
138 | }
139 |
140 | /**
141 | * @test
142 | */
143 | public function it_sets_the_expected_header_for_reply_to()
144 | {
145 | $this->mailer->setReplyTo($this->email, $this->name);
146 | $header = sprintf('%s: %s', 'Reply-To', $this->mailer->formatHeader($this->email, $this->name));
147 |
148 | $this->assertContains($header, $this->mailer->getHeaders());
149 | }
150 |
151 | /**
152 | * @test
153 | */
154 | public function testSetWrapAssignsCorrectValue()
155 | {
156 | $this->mailer->setWrap(50);
157 |
158 | $this->assertSame(50, $this->mailer->getWrap());
159 | }
160 |
161 | /**
162 | * @test
163 | */
164 | public function it_defaults_message_wrapping_to_expected_number_when_wrap_is_set_to_zero()
165 | {
166 | $this->mailer->setWrap(0);
167 | $this->assertSame(78, $this->mailer->getWrap());
168 | }
169 |
170 | /**
171 | * @test
172 | */
173 | public function it_defaults_message_wrapping_to_expected_number()
174 | {
175 | $this->assertSame(78, $this->mailer->getWrap());
176 | }
177 |
178 | /**
179 | * @test
180 | */
181 | public function it_returns_the_correct_parameters()
182 | {
183 | $this->mailer->setParameters("-fuse@gmail.com");
184 | $params = $this->mailer->getParameters();
185 | $this->assertSame("-fuse@gmail.com", $params);
186 | }
187 |
188 | /**
189 | * @test
190 | */
191 | public function it_returns_the_correct_header_when_addGenericHeader_is_called_with_valid_arguments()
192 | {
193 | $this->mailer->addGenericHeader('Version', 'PHP5');
194 | $this->assertContains("Version: PHP5", $this->mailer->getHeaders());
195 | }
196 |
197 | /**
198 | * @test
199 | */
200 | public function it_returns_the_correct_header_when_addMailHeader_is_called_without_name()
201 | {
202 | $this->mailer->addMailHeader('Cc', $this->email);
203 | $this->assertContains("Cc: " . $this->email, $this->mailer->getHeaders());
204 | }
205 |
206 | /**
207 | * @test
208 | */
209 | public function it_returns_the_correct_header_when_addMailHeaders_is_called_without_name_keys()
210 | {
211 | $this->mailer->addMailHeaders('Cc', array(
212 | 'jim@gmail.com', 'joe@gmail.com'
213 | ));
214 |
215 | $headers = $this->mailer->getHeaders();
216 |
217 | $this->assertContains("Cc: jim@gmail.com,joe@gmail.com", $headers);
218 | }
219 |
220 | /**
221 | * @test
222 | */
223 | public function it_allows_multiple_mail_headers_to_be_added_with_email_and_name_pairs()
224 | {
225 | $name1 = 'Jim Smith';
226 | $name2 = 'Joe Smith';
227 |
228 | $email1 = 'jim@gmail.com';
229 | $email2 = 'joe@gmail.com';
230 |
231 | $addresses = array(
232 | $name1 => $email1,
233 | $name2 => $email2,
234 | );
235 |
236 | $this->mailer->addMailHeaders('Bcc', $addresses);
237 |
238 | $expected = sprintf("Bcc: %s,%s",
239 | $this->mailer->formatHeader($email1, $name1),
240 | $this->mailer->formatHeader($email2, $name2)
241 | );
242 |
243 | $this->assertContains($expected, $this->mailer->getHeaders());
244 | }
245 |
246 | /**
247 | * @test
248 | * @expectedException InvalidArgumentException
249 | */
250 | public function it_throws_exception_when_adding_mail_headers_without_email_and_name_pairs()
251 | {
252 | $this->mailer->addMailHeaders('Bcc', array());
253 | }
254 |
255 | /**
256 | * @test
257 | */
258 | public function it_formats_header_without_name_and_returns_only_the_email()
259 | {
260 | $email = 'test@domain.tld';
261 | $header = $this->mailer->formatHeader($email);
262 |
263 | $this->assertSame($email, $header);
264 | }
265 |
266 | /**
267 | * @test
268 | */
269 | public function it_can_return_debug_information()
270 | {
271 | $this->assertSame($this->mailer->debug(), ''.print_r($this->mailer, 1).'
');
272 | }
273 |
274 | /**
275 | * @test
276 | */
277 | public function it_can_convert_the_object_to_a_string()
278 | {
279 | $stringObject = print_r($this->mailer, 1);
280 |
281 | $this->assertSame((string) $this->mailer, $stringObject);
282 | }
283 |
284 | /**
285 | * @test
286 | */
287 | public function it_will_return_true_when_hasAttachments_called_with_attachment_already_passed()
288 | {
289 | $this->mailer->addAttachment($this->directory.'/example/pbXBsZSwgY2hh.jpg', 'lolcat_finally_arrived.jpg');
290 |
291 | $this->assertTrue($this->mailer->hasAttachments());
292 | }
293 |
294 | /**
295 | * @test
296 | */
297 | public function it_will_return_false_when_hasAttachments_called_with_no_attachment_passed()
298 | {
299 | $this->assertFalse($this->mailer->hasAttachments());
300 | }
301 |
302 | /**
303 | * @test
304 | */
305 | public function it_assembles_the_correct_headers_when_adding_attachments()
306 | {
307 | $this->mailer->addAttachment($this->directory.'/example/pbXBsZSwgY2hh.jpg', 'lolcat_finally_arrived.jpg');
308 |
309 | $this->assertTrue(is_string($this->mailer->assembleAttachmentHeaders()));
310 | }
311 |
312 | /**
313 | * @test
314 | * @expectedException RuntimeException
315 | */
316 | public function it_throws_a_runtime_exception_when_no_to_address_is_set()
317 | {
318 | $this->mailer->send();
319 | }
320 |
321 | /**
322 | * @test
323 | */
324 | public function it_returns_a_boolean_from_send()
325 | {
326 | $this->mailer->setTo($this->email, $this->name)
327 | ->setFrom($this->email, $this->name)
328 | ->setSubject('Hello From PHPUnit')
329 | ->setMessage('Hello message.');
330 |
331 | $bool = $this->mailer->send();
332 | $this->assertTrue(is_bool($bool));
333 | }
334 |
335 | /**
336 | * @test
337 | */
338 | public function it_returns_a_boolean_when_sending_with_attachment()
339 | {
340 | $this->mailer->setTo($this->email, $this->name)
341 | ->setFrom($this->email, $this->name)
342 | ->setSubject('Hello From PHPUnit')
343 | ->setMessage('Hello message.')
344 | ->addAttachment($this->directory.'/example/pbXBsZSwgY2hh.jpg', 'lolcat_finally_arrived.jpg');
345 |
346 | $bool = $this->mailer->send();
347 | $this->assertTrue(is_bool($bool));
348 | }
349 |
350 | /**
351 | * @test
352 | */
353 | public function it_filters_out_carriage_returns_from_names()
354 | {
355 | $string = "\rHello World";
356 | $name = $this->mailer->filterName("\rHello World");
357 |
358 | $this->assertNotSame($string, $name);
359 | }
360 |
361 | /**
362 | * @test
363 | */
364 | public function it_filters_out_new_lines_from_names()
365 | {
366 | $string = "\nHello World";
367 | $name = $this->mailer->filterName($string);
368 |
369 | $this->assertNotSame($string, $name);
370 | }
371 |
372 | /**
373 | * @test
374 | */
375 | public function it_filters_out_tab_characters_from_names()
376 | {
377 | $string = "\tHello World\t";
378 | $name = $this->mailer->filterName($string);
379 |
380 | $this->assertNotSame($string, $name);
381 | }
382 |
383 | /**
384 | * @test
385 | */
386 | public function it_replaces_double_quotes_with_single_quote_entities_for_names()
387 | {
388 | $expected = "'Hello World'";
389 | $name = $this->mailer->filterName('"Hello World"');
390 |
391 | $this->assertEquals($expected, $name);
392 | }
393 |
394 | public function it_filters_out_angle_brackets_from_names()
395 | {
396 | $expected = 'Hello World';
397 | $name = $this->mailer->filterName('<> Hello World');
398 |
399 | $this->assertEquals($expected, $name);
400 | }
401 |
402 | /**
403 | * @test
404 | */
405 | public function it_filters_out_carriage_returns_from_other_data()
406 | {
407 | $expected = 'Hello World';
408 | $actual = $this->mailer->filterOther("\rHello World");
409 | $this->assertSame($expected, $actual);
410 | }
411 |
412 | /**
413 | * @test
414 | */
415 | public function it_filters_out_new_lines_from_other_data()
416 | {
417 | $expected = 'Hello World';
418 | $actual = $this->mailer->filterOther("\nHello World");
419 | $this->assertSame($expected, $actual);
420 | }
421 |
422 | /**
423 | * @test
424 | */
425 | public function it_filters_out_tab_characters_from_other_data()
426 | {
427 | $expected = 'Hello World';
428 | $actual = $this->mailer->filterOther("\tHello World");
429 | $this->assertSame($expected, $actual);
430 | }
431 |
432 | /**
433 | * @test
434 | */
435 | public function it_does_not_filter_out_quotes_from_other_data()
436 | {
437 | $expected = 'Hello "World"';
438 | $actual = $this->mailer->filterOther($expected);
439 | $this->assertSame($expected, $actual);
440 | }
441 |
442 | /**
443 | * @test
444 | */
445 | public function it_does_not_filter_out_tags_from_other_data()
446 | {
447 | $expected = 'Hello ';
448 | $actual = $this->mailer->filterOther($expected);
449 | $this->assertSame($expected, $actual);
450 | }
451 |
452 | /**
453 | * @test
454 | */
455 | public function it_does_not_filter_high_ascii_from_other_data()
456 | {
457 | $expected = "Hej världen!";
458 | $actual = $this->mailer->filterOther($expected);
459 | $this->assertSame($expected, $actual);
460 | }
461 |
462 | /**
463 | * @test
464 | */
465 | public function it_filters_carriage_returns_from_emails()
466 | {
467 | $string = "test@test.com\r";
468 | $name = $this->mailer->filterEmail($string);
469 |
470 | $this->assertNotSame($string, $name);
471 | }
472 |
473 | /**
474 | * @test
475 | */
476 | public function it_filters_new_lines_from_emails()
477 | {
478 | $string = "test@test.com\n";
479 | $name = $this->mailer->filterEmail($string);
480 |
481 | $this->assertNotSame($string, $name);
482 | }
483 |
484 | /**
485 | * @test
486 | */
487 | public function it_filters_tabbed_characters_from_emails()
488 | {
489 | $string = "\ttest@test.com\t";
490 | $name = $this->mailer->filterEmail($string);
491 |
492 | $this->assertNotSame($string, $name);
493 | }
494 |
495 | /**
496 | * @test
497 | */
498 | public function it_filters_double_quotes_from_emails()
499 | {
500 | $expected = "test@test.com";
501 | $name = $this->mailer->filterEmail('"test@test.com"');
502 |
503 | $this->assertEquals($expected, $name);
504 | }
505 |
506 | /**
507 | * @test
508 | */
509 | public function it_filters_commas_from_emails()
510 | {
511 | $expected = "test@test.com";
512 | $name = $this->mailer->filterEmail('t,es,t@test.com');
513 |
514 | $this->assertEquals($expected, $name);
515 | }
516 |
517 | /**
518 | * @test
519 | */
520 | public function it_filters_angle_brackets_from_emails()
521 | {
522 | $expected = 'test@test.com';
523 | $name = $this->mailer->filterEmail('');
524 |
525 | $this->assertEquals($expected, $name);
526 | }
527 |
528 | /**
529 | * @test
530 | */
531 | public function it_quoted_printable_encodes_attachment_message_bodies()
532 | {
533 | $message = "J'interdis aux marchands de vanter trop leur marchandises. Car ils se font vite pédagogues et t'enseignent comme but ce qui n'est par essence qu'un moyen, et te trompant ainsi sur la route à suivre les voilà bientôt qui te dégradent, car si leur musique est vulgaire ils te fabriquent pour te la vendre une âme vulgaire.";
534 |
535 | $this->mailer->setMessage($message)
536 | ->addAttachment($this->directory . '/example/pbXBsZSwgY2hh.jpg', 'lolcat_finally_arrived.jpg');
537 |
538 | $body = $this->mailer->assembleAttachmentBody();
539 | $this->assertRegExp('/^Content-Transfer-Encoding: quoted-printable$/m', $body);
540 | }
541 |
542 | public function tearDown()
543 | {
544 | unset($this->mailer);
545 | }
546 | }
547 |
--------------------------------------------------------------------------------