From cd71a8439c323c31c8e2724d8e618ee6b3a73fb8 Mon Sep 17 00:00:00 2001 From: Maurits van der Schee Date: Fri, 28 Jun 2013 00:46:34 +0200 Subject: [PATCH] Add option to send email attachment from string (not only from file). I would be very pleased if this option would be available in some future version. Thank you. --- lib/Cake/Network/Email/CakeEmail.php | 36 +++++++++++++----- .../Test/Case/Network/Email/CakeEmailTest.php | 37 +++++++++++++++++++ 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/lib/Cake/Network/Email/CakeEmail.php b/lib/Cake/Network/Email/CakeEmail.php index 66be98884..cbe89f780 100644 --- a/lib/Cake/Network/Email/CakeEmail.php +++ b/lib/Cake/Network/Email/CakeEmail.php @@ -953,6 +953,15 @@ class CakeEmail { * '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 `` to display the image inline. @@ -974,14 +983,21 @@ class CakeEmail { $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'; @@ -1388,7 +1404,7 @@ class CakeEmail { 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']; @@ -1433,7 +1449,7 @@ class CakeEmail { 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']; diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index a490f94e4..3fdd25117 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -856,6 +856,43 @@ class CakeEmailTest extends CakeTestCase { $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 *