|
| 1 | +# Adding Attachments |
| 2 | + |
| 3 | +zend-mail does not directly provide the ability to create and use mail |
| 4 | +attachments. However, it allows using `Zend\Mime\Message` instances, from the |
| 5 | +[zend-mime](https://github.com/zendframework/zend-mime) component, for message |
| 6 | +bodies, allowing you to create multipart emails. |
| 7 | + |
| 8 | +## Basic multipart content |
| 9 | + |
| 10 | +The following example creates an email with two parts, HTML content and an |
| 11 | +image. |
| 12 | + |
| 13 | +```php |
| 14 | +use Zend\Mail\Message; |
| 15 | +use Zend\Mime\Message as MimeMessage; |
| 16 | +use Zend\Mime\Mime; |
| 17 | +use Zend\Mime\Part as MimePart; |
| 18 | + |
| 19 | +$html = new MimePart($htmlMarkup); |
| 20 | +$html->type = Mime::TYPE_HTML; |
| 21 | +$html->charset = 'utf-8'; |
| 22 | +$html->encoding = Mime::ENCODING_QUOTEDPRINTABLE; |
| 23 | + |
| 24 | +$image = new MimePart(fopen($pathToImage, 'r')); |
| 25 | +$image->type = 'image/jpeg'; |
| 26 | +$image->filename = 'image-file-name.jpg'; |
| 27 | +$image->disposition = Mime::DISPOSITION_ATTACHMENT; |
| 28 | +$image->encoding = Mime::ENCODING_BASE64; |
| 29 | + |
| 30 | +$body = new MimeMessage(); |
| 31 | +$body->setParts([$html, $image]); |
| 32 | + |
| 33 | +$message = new Message(); |
| 34 | +$message->setBody($body); |
| 35 | +$message->getHeaders()->addHeaderLine('Content-Type', 'multipart/related'); |
| 36 | +``` |
| 37 | + |
| 38 | +Note that the above code requires us to manually specify the message content |
| 39 | +type; zend-mime does not automatically select the multipart type for us, nor |
| 40 | +does zend-mail populate it by default. |
| 41 | + |
| 42 | +## multipart/alternative content |
| 43 | + |
| 44 | +One of the most common email types sent by web applications is |
| 45 | +`multipart/alternative` messages with both text and HTML parts. |
| 46 | + |
| 47 | +```php |
| 48 | +use Zend\Mail\Message; |
| 49 | +use Zend\Mime\Message as MimeMessage; |
| 50 | +use Zend\Mime\Mime; |
| 51 | +use Zend\Mime\Part as MimePart; |
| 52 | + |
| 53 | +$text = new MimePart($textContent); |
| 54 | +$text->type = Mime::TYPE_TEXT; |
| 55 | +$text->charset = 'utf-8'; |
| 56 | +$text->encoding = Mime::ENCODING_QUOTEDPRINTABLE; |
| 57 | + |
| 58 | +$html = new MimePart($htmlMarkup); |
| 59 | +$html->type = Mime::TYPE_HTML; |
| 60 | +$html->charset = 'utf-8'; |
| 61 | +$html->encoding = Mime::ENCODING_QUOTEDPRINTABLE; |
| 62 | + |
| 63 | +$body = new MimeMessage(); |
| 64 | +$body->setParts([$text, $html]); |
| 65 | + |
| 66 | +$message = new Message(); |
| 67 | +$message->setBody($body); |
| 68 | +$message->getHeaders()->addHeaderLine('Content-Type', 'multipart/alternative'); |
| 69 | +``` |
| 70 | + |
| 71 | +The only differences from the first example are: |
| 72 | + |
| 73 | +- We have text and HTML parts instead of an HTML and image part. |
| 74 | +- The `Content-Type` header is now `multipart/alternative`. |
| 75 | + |
| 76 | +## multipart/alternative emails with attachments |
| 77 | + |
| 78 | +Another common task is creating `multipart/alternative` emails where the HTML |
| 79 | +content refers to assets attachments (images, CSS, etc.). |
| 80 | + |
| 81 | +To accomplish this, we need to: |
| 82 | + |
| 83 | +- Create a `Zend\Mime\Part` instance containing our `multipart/alternative` |
| 84 | + message. |
| 85 | +- Add that part to a `Zend\Mime\Message`. |
| 86 | +- Add additional `Zend\Mime\Part` instances to the MIME message. |
| 87 | +- Attach the MIME message as the `Zend\Mail\Message` content body. |
| 88 | +- Mark the message as `multipart/related` content. |
| 89 | + |
| 90 | +The following example creates a MIME message with three parts: text and HTML |
| 91 | +alternative versions of an email, and an image attachment. |
| 92 | + |
| 93 | +```php |
| 94 | +use Zend\Mail\Message; |
| 95 | +use Zend\Mime\Message as MimeMessage; |
| 96 | +use Zend\Mime\Mime; |
| 97 | +use Zend\Mime\Part as MimePart; |
| 98 | + |
| 99 | +$body = new MimeMessage(); |
| 100 | + |
| 101 | +$text = new MimePart($textContent); |
| 102 | +$text->type = Mime::TYPE_TEXT; |
| 103 | +$text->charset = 'utf-8'; |
| 104 | +$text->encoding = Mime::ENCODING_QUOTEDPRINTABLE; |
| 105 | + |
| 106 | +$html = new MimePart($htmlMarkup); |
| 107 | +$html->type = Mime::TYPE_HTML; |
| 108 | +$html->charset = 'utf-8'; |
| 109 | +$html->encoding = Mime::ENCODING_QUOTEDPRINTABLE; |
| 110 | + |
| 111 | +$content = new MimeMessage(); |
| 112 | +$content->setParts([$text, $html]); |
| 113 | + |
| 114 | +$contentPart = new MimePart($content->generateMessage()); |
| 115 | +$contentPart->type = sprintf( |
| 116 | + "multipart/alternative\n boundary=\"%s\", |
| 117 | + $content->getMime()->boundary() |
| 118 | +); |
| 119 | + |
| 120 | +$image = new MimePart(fopen($pathToImage, 'r')); |
| 121 | +$image->type = 'image/jpeg'; |
| 122 | +$image->filename = 'image-file-name.jpg'; |
| 123 | +$image->disposition = Mime::DISPOSITION_ATTACHMENT; |
| 124 | +$image->encoding = Mime::ENCODING_BASE64; |
| 125 | + |
| 126 | +$body = new MimeMessage(); |
| 127 | +$body->setParts([$contentPart, $image]); |
| 128 | + |
| 129 | +$message = new Message(); |
| 130 | +$message->setBody($body); |
| 131 | +$message->geHeaders()->addHeaderLine('Content-Type', 'multipart/related'); |
| 132 | +``` |
| 133 | + |
| 134 | +## Setting custom MIME boundaries |
| 135 | + |
| 136 | +In a multipart message, a MIME boundary for separating the different parts of |
| 137 | +the message is normally generated at random. In some cases, however, you might |
| 138 | +want to specify the MIME boundary that is used. This can be done by injecting a |
| 139 | +new `Zend\Mime\Mime` instance into the MIME message. |
| 140 | + |
| 141 | +```php |
| 142 | +use Zend\Mime\Mime; |
| 143 | + |
| 144 | +$mimeMessage->setMime(new Mime($customBoundary)); |
| 145 | +``` |
0 commit comments