Skip to content

Commit

Permalink
Add option to send email attachment from string (not only from file).
Browse files Browse the repository at this point in the history
I would be very pleased if this option would be available in some
future version. Thank you.
  • Loading branch information
Maurits van der Schee committed Jun 28, 2013
1 parent 6fdbdf5 commit cd71a84
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 10 deletions.
36 changes: 26 additions & 10 deletions lib/Cake/Network/Email/CakeEmail.php
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,15 @@ public function domain($domain = null) {
* 'contentDisposition' => false
* ));
* }}}
*
* Attach a file from string and specify additional properties:
*
* {{{
* $email->attachments(array('custom_name.png' => array(
* 'data' => file_get_contents('path/to/file'),
* 'mimetype' => 'image/png'
* ));
* }}}
*
* The `contentId` key allows you to specify an inline attachment. In your email text, you
* can use `<img src="cid:abc123" />` to display the image inline.
Expand All @@ -974,14 +983,21 @@ public function attachments($attachments = null) {
$fileInfo = array('file' => $fileInfo);
}
if (!isset($fileInfo['file'])) {
throw new SocketException(__d('cake_dev', 'File not specified.'));
}
$fileInfo['file'] = realpath($fileInfo['file']);
if ($fileInfo['file'] === false || !file_exists($fileInfo['file'])) {
throw new SocketException(__d('cake_dev', 'File not found: "%s"', $fileInfo['file']));
}
if (is_int($name)) {
$name = basename($fileInfo['file']);
if (!isset($fileInfo['data'])) {
throw new SocketException(__d('cake_dev', 'No file or data specified.'));
}
if (is_int($name)) {
throw new SocketException(__d('cake_dev', 'No filename specified.'));
}
$fileInfo['data'] = chunk_split(base64_encode($fileInfo['data']), 76, "\r\n");
} else {
$fileInfo['file'] = realpath($fileInfo['file']);
if ($fileInfo['file'] === false || !file_exists($fileInfo['file'])) {
throw new SocketException(__d('cake_dev', 'File not found: "%s"', $fileInfo['file']));
}
if (is_int($name)) {
$name = basename($fileInfo['file']);
}
}
if (!isset($fileInfo['mimetype'])) {
$fileInfo['mimetype'] = 'application/octet-stream';
Expand Down Expand Up @@ -1388,7 +1404,7 @@ protected function _attachFiles($boundary = null) {
if (!empty($fileInfo['contentId'])) {
continue;
}
$data = $this->_readFile($fileInfo['file']);
$data = isset($fileInfo['data']) ? $fileInfo['data'] : $this->_readFile($fileInfo['file']);

$msg[] = '--' . $boundary;
$msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
Expand Down Expand Up @@ -1433,7 +1449,7 @@ protected function _attachInlineFiles($boundary = null) {
if (empty($fileInfo['contentId'])) {
continue;
}
$data = $this->_readFile($fileInfo['file']);
$data = isset($fileInfo['data']) ? $fileInfo['data'] : $this->_readFile($fileInfo['file']);

$msg[] = '--' . $boundary;
$msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
Expand Down
37 changes: 37 additions & 0 deletions lib/Cake/Test/Case/Network/Email/CakeEmailTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,43 @@ public function testSendNoTemplateWithAttachments() {
$this->assertContains($expected, $result['message']);
}

/**
* Test send() with no template and data string attachment
*
* @return void
*/

public function testSendNoTemplateWithDataStringAttachment() {
$this->CakeEmail->transport('debug');
$this->CakeEmail->from('cake@cakephp.org');
$this->CakeEmail->to('cake@cakephp.org');
$this->CakeEmail->subject('My title');
$this->CakeEmail->emailFormat('text');
$data = file_get_contents(CAKE . 'Console/Templates/skel/webroot/img/cake.icon.png');
$this->CakeEmail->attachments(array('cake.icon.png' => array(
'data' => $data,
'mimetype' => 'image/png'
)));
$result = $this->CakeEmail->send('Hello');

$boundary = $this->CakeEmail->getBoundary();
$this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
$expected = "--$boundary\r\n" .
"Content-Type: text/plain; charset=UTF-8\r\n" .
"Content-Transfer-Encoding: 8bit\r\n" .
"\r\n" .
"Hello" .
"\r\n" .
"\r\n" .
"\r\n" .
"--$boundary\r\n" .
"Content-Type: image/png\r\n" .
"Content-Transfer-Encoding: base64\r\n" .
"Content-Disposition: attachment; filename=\"cake.icon.png\"\r\n\r\n";
$expected .= chunk_split(base64_encode($data), 76, "\r\n");
$this->assertContains($expected, $result['message']);
}

/**
* Test send() with no template as both
*
Expand Down

0 comments on commit cd71a84

Please sign in to comment.