├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENCE.txt ├── README.md ├── class.simple_mail.php ├── composer.json ├── example ├── example.php ├── example_attachment.php ├── example_attachment_textfile.php ├── lolcat_what.jpg ├── pbXBsZSwgY2hh.jpg └── test.txt ├── phpunit.xml └── tests └── class.simple_mail.test.php /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | coverage/ 3 | .DS_Store 4 | clover.xml 5 | .scrutinizer.yml 6 | scrutinizer.phar 7 | /vendor/* 8 | /composer.lock -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.4 5 | - 5.5 6 | - 5.6 7 | - 7.0 8 | - 8.0 9 | - 8.1 10 | 11 | cache: 12 | directories: 13 | - $HOME/.composer/cache 14 | - vendor 15 | 16 | install: 17 | - composer install 18 | 19 | script: 20 | - composer run-script test-build 21 | - wget https://scrutinizer-ci.com/ocular.phar 22 | - php ocular.phar code-coverage:upload --format=php-clover coverage.clover 23 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # CONTRIBUTING 2 | 3 | ## RESOURCES 4 | 5 | If you wish to contribute to PHP Simple Mail, please be sure to 6 | read to the following resources: 7 | 8 | - Coding Standards: 9 | http://framework.zend.com/manual/1.12/en/coding-standard.coding-style.html 10 | - LICENCE.txt 11 | 12 | If you are committing a pull request, please add tests for your changes before you commit. 13 | 14 | ## RUNNING TESTS 15 | 16 | To run tests: 17 | 18 | - In the root directory, run `phpunit` -------------------------------------------------------------------------------- /LICENCE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Eoghan O'Brien 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [![Build Status](https://travis-ci.org/eoghanobrien/php-simple-mail.png?branch=master)](https://travis-ci.org/eoghanobrien/php-simple-mail) 4 | [![Latest Stable Version](https://poser.pugx.org/eoghanobrien/php-simple-mail/v/stable.png)](https://packagist.org/packages/eoghanobrien/php-simple-mail) 5 | [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/eoghanobrien/php-simple-mail/badges/quality-score.png?s=a6850c4ef51c0d56ed50513d3749d6c1617dfaff)](https://scrutinizer-ci.com/g/eoghanobrien/php-simple-mail/) 6 | [![Code Coverage](https://scrutinizer-ci.com/g/eoghanobrien/php-simple-mail/badges/coverage.png?s=d167e7faf23471deeef69d26ff23812a64e74326)](https://scrutinizer-ci.com/g/eoghanobrien/php-simple-mail/) 7 | [![Total Downloads](https://poser.pugx.org/eoghanobrien/php-simple-mail/downloads.png)](https://packagist.org/packages/eoghanobrien/php-simple-mail) 8 | [![License](https://poser.pugx.org/eoghanobrien/php-simple-mail/license.png)](https://packagist.org/packages/eoghanobrien/php-simple-mail) 9 | [![PHP 7 ready](http://php7ready.timesplinter.ch/eoghanobrien/php-simple-mail/master/badge.svg)](https://travis-ci.org/eoghanobrien/php-simple-mail) 10 | 11 | ## Introduction 12 | 13 | Simple Mail Class provides a simple, chainable wrapper for creating and sending emails using the PHP `mail()` function. There are better options out there for sending SMTP email, which are more secure and more reliable than the `mail()` function. However, sometimes you just need to send a simple email. That's what we cover. 14 | 15 | ## Installation via Composer 16 | 17 | ``` 18 | $ composer require eoghanobrien/php-simple-mail 19 | ``` 20 | 21 | ## Usage 22 | 23 | ### Instantiating the class. 24 | 25 | You have two options, you can 'new up' the class in the traditional way: 26 | 27 | ```php 28 | $mailer = new SimpleMail(); 29 | ``` 30 | or instantiate it using the named static constructor `make()` 31 | ```php 32 | $mailer = SimpleMail::make(); 33 | ``` 34 | The static constructor can be useful when you want to continue chaining methods after instantiating. 35 | ```php 36 | SimpleMail::make() 37 | ->setTo($email, $name) 38 | ->setFrom($fromEmail, $fromName) 39 | ->setSubject($subject) 40 | ->setMessage($message) 41 | ->send(); 42 | ``` 43 | 44 | 45 | 46 | ### `To` header 47 | 48 | The `To` header can be called multiple time, in order to pass more than one `To` address, simply call the `setTo` method as many times as needed. It takes two string parameters. The first parameter is for the email address, the second is for the name. 49 | 50 | ```php 51 | SimpleMail::make() 52 | ->setTo($email1, $name1) 53 | ->setTo($email2, $name2); 54 | ``` 55 | 56 | 57 | ### `From` header 58 | 59 | You can carbon copy one or more addresses using the `setBcc` method. It takes two string parameters. The first parameter is for the email address, the second is for the name. 60 | 61 | ```php 62 | SimpleMail::make() 63 | ->setFrom('john.smith@example.com', 'John Smith'); 64 | ``` 65 | 66 | 67 | 68 | ### `Cc` header 69 | 70 | You can carbon copy one or more addresses using the `setCc` method. It takes an array of `$name => $email` pairs. Alternatively, you can pass a simple numerically keyed array an the value is assumed to be the email. 71 | 72 | ```php 73 | SimpleMail::make() 74 | ->setCc(['John Smith', 'john.smith@example.com'); 75 | ``` 76 | 77 | 78 | ### `Bcc` header 79 | 80 | You can blind carbon copy one or more addresses using the `setBcc` method. It takes an array of `$name => $email` pairs. Alternatively, you can pass a simple numerically keyed array an the value is assumed to be the email. 81 | 82 | ```php 83 | SimpleMail::make() 84 | ->setBcc(['John Smith', 'john.smith@example.com'); 85 | ``` 86 | 87 | ### `Subject` header 88 | 89 | You can set the subject using `setSubject` method. It takes a string as the only parameter. 90 | 91 | ```php 92 | SimpleMail::make() 93 | ->setSubject("Important information about your account"); 94 | ``` 95 | 96 | ### `Message` header 97 | 98 | You can set the message using `setMessage` method. It takes a string as the only parameter. 99 | 100 | ```php 101 | SimpleMail::make() 102 | ->setMessage("My important message!"); 103 | ``` 104 | 105 | ### `HTML` emails 106 | 107 | If you want to include HTML in your email. Simply call the `setHtml()` method. It takes no parameters. 108 | 109 | ```php 110 | SimpleMail::make() 111 | ->setMessage("My important message!") 112 | ->setHtml(); 113 | ``` 114 | 115 | ### `send` emails 116 | 117 | Once you've set all your headers. Use the `send()` method to finally send it on it's way. 118 | 119 | ```php 120 | SimpleMail::make() 121 | ->setMessage("My important message!") 122 | ->send(); 123 | ``` 124 | 125 | ### Full example of sending an email 126 | 127 | ```php 128 | $send = SimpleMail::make() 129 | ->setTo($email, $name) 130 | ->setFrom($fromEmail, $fromName) 131 | ->setSubject($subject) 132 | ->setMessage($message) 133 | ->setReplyTo($replyEmail, $replyName) 134 | ->setCc(['Bill Gates' => 'bill@example.com']) 135 | ->setBcc(['Steve Jobs' => 'steve@example.com']) 136 | ->setHtml() 137 | ->setWrap(100) 138 | ->send(); 139 | 140 | echo ($send) ? 'Email sent successfully' : 'Could not send email'; 141 | ``` 142 | 143 | ### Example of sending an email with attachments 144 | 145 | If you are sending an attachment there is no need to add any addGenericHeader()'s. To properly send the attachments the necessary headers will be set for you. You can also chain as many attachments as you want (see example). 146 | 147 | ```php 148 | $send = SimpleMail::make() 149 | ->setTo($email, $name) 150 | ->setFrom($fromEmail, $fromName) 151 | ->setSubject($subject) 152 | ->setMessage($message) 153 | ->setReplyTo($replyEmail, $replyName) 154 | ->setCc(['Bill Gates' => 'bill@example.com']) 155 | ->setBcc(['Steve Jobs' => 'steve@example.com']) 156 | ->setHtml() 157 | ->setWrap(100) 158 | ->addAttachment('example/pbXBsZSwgY2hh.jpg', 'lolcat_finally_arrived.jpg') 159 | ->addAttachment('example/lolcat_what.jpg') 160 | ->send(); 161 | 162 | echo ($send) ? 'Email sent successfully' : 'Could not send email'; 163 | ``` 164 | 165 | ## License 166 | php-simple-mail is free and unencumbered public domain software. For more information, see [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT) or the accompanying MIT file. 167 | 168 | -------------------------------------------------------------------------------- /class.simple_mail.php: -------------------------------------------------------------------------------- 1 | 5.2 8 | * 9 | * LICENSE: This source file is subject to the MIT license, which is 10 | * available through the world-wide-web at the following URI: 11 | * http://github.com/eoghanobrien/php-simple-mail/LICENCE.txt 12 | * 13 | * @category SimpleMail 14 | * @package SimpleMail 15 | * @author Eoghan O'Brien 16 | * @copyright 2009 - 2017 Eoghan O'Brien 17 | * @license http://github.com/eoghanobrien/php-simple-mail/LICENCE.txt MIT 18 | * @version 1.7.1 19 | * @link http://github.com/eoghanobrien/php-simple-mail 20 | */ 21 | 22 | /** 23 | * Simple Mail class. 24 | * 25 | * @category SimpleMail 26 | * @package SimpleMail 27 | * @author Eoghan O'Brien 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 | --------------------------------------------------------------------------------