Browse Source

Adapted to support mimetype and contentId in the attachments. Fixes #1201.

Juan Basso 15 years ago
parent
commit
599d631f2f
2 changed files with 62 additions and 17 deletions
  1. 25 11
      lib/Cake/Network/CakeEmail.php
  2. 37 6
      lib/Cake/tests/Case/Network/CakeEmailTest.php

+ 25 - 11
lib/Cake/Network/CakeEmail.php

@@ -804,15 +804,24 @@ class CakeEmail {
 			return $this->_attachments;
 		}
 		$attach = array();
-		foreach ((array)$attachments as $name => $file) {
-			$path = realpath($file);
-			if ($path === false) {
-				throw new SocketException(__d('cake', 'File not found: "%s"', $attach));
+		foreach ((array)$attachments as $name => $fileInfo) {
+			if (!is_array($fileInfo)) {
+				$fileInfo = array('file' => $fileInfo);
+			}
+			if (!isset($fileInfo['file'])) {
+				throw new SocketException(__d('cake', 'File not specified.'));
+			}
+			$fileInfo['file'] = realpath($fileInfo['file']);
+			if ($fileInfo['file'] === false || !file_exists($fileInfo['file'])) {
+				throw new SocketException(__d('cake', 'File not found: "%s"', $fileInfo['file']));
 			}
 			if (is_int($name)) {
-				$name = basename($path);
+				$name = basename($fileInfo['file']);
+			}
+			if (!isset($fileInfo['mimetype'])) {
+				$fileInfo['mimetype'] = 'application/octet-stream';
 			}
-			$attach[$name] = $path;
+			$attach[$name] = $fileInfo;
 		}
 		$this->_attachments = $attach;
 		return $this;
@@ -1191,16 +1200,21 @@ class CakeEmail {
  * @return void
  */
 	protected function _attachFiles() {
-		foreach ($this->_attachments as $filename => $file) {
-			$handle = fopen($file, 'rb');
-			$data = fread($handle, filesize($file));
+		foreach ($this->_attachments as $filename => $fileInfo) {
+			$handle = fopen($fileInfo['file'], 'rb');
+			$data = fread($handle, filesize($fileInfo['file']));
 			$data = chunk_split(base64_encode($data)) ;
 			fclose($handle);
 
 			$this->_message[] = '--' . $this->_boundary;
-			$this->_message[] = 'Content-Type: application/octet-stream';
+			$this->_message[] = 'Content-Type: ' . $fileInfo['mimetype'];
 			$this->_message[] = 'Content-Transfer-Encoding: base64';
-			$this->_message[] = 'Content-Disposition: attachment; filename="' . $filename . '"';
+			if (empty($fileInfo['contentId'])) {
+				$this->_message[] = 'Content-Disposition: attachment; filename="' . $filename . '"';
+			} else {
+				$this->_message[] = 'Content-ID: <' . $fileInfo['contentId'] . '>';
+				$this->_message[] = 'Content-Disposition: inline; filename="' . $filename . '"';
+			}
 			$this->_message[] = '';
 			$this->_message[] = $data;
 			$this->_message[] = '';

+ 37 - 6
lib/Cake/tests/Case/Network/CakeEmailTest.php

@@ -492,21 +492,21 @@ class CakeEmailTest extends CakeTestCase {
  */
 	public function testAttachments() {
 		$this->CakeEmail->attachments(WWW_ROOT . 'index.php');
-		$expected = array('index.php' => WWW_ROOT . 'index.php');
+		$expected = array('index.php' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'application/octet-stream'));
 		$this->assertIdentical($this->CakeEmail->attachments(), $expected);
 
 		$this->CakeEmail->attachments(array());
 		$this->assertIdentical($this->CakeEmail->attachments(), array());
 
-		$this->CakeEmail->attachments(WWW_ROOT . 'index.php');
+		$this->CakeEmail->attachments(array(array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain')));
 		$this->CakeEmail->addAttachments(WWW_ROOT . 'test.php');
 		$this->CakeEmail->addAttachments(array(WWW_ROOT . 'test.php'));
 		$this->CakeEmail->addAttachments(array('other.txt' => WWW_ROOT . 'test.php', 'ht' => WWW_ROOT . '.htaccess'));
 		$expected = array(
-			'index.php' => WWW_ROOT . 'index.php',
-			'test.php' => WWW_ROOT . 'test.php',
-			'other.txt' => WWW_ROOT . 'test.php',
-			'ht' => WWW_ROOT . '.htaccess'
+			'index.php' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain'),
+			'test.php' => array('file' => WWW_ROOT . 'test.php', 'mimetype' => 'application/octet-stream'),
+			'other.txt' => array('file' => WWW_ROOT . 'test.php', 'mimetype' => 'application/octet-stream'),
+			'ht' => array('file' => WWW_ROOT . '.htaccess', 'mimetype' => 'application/octet-stream')
 		);
 		$this->assertIdentical($this->CakeEmail->attachments(), $expected);
 	}
@@ -656,6 +656,37 @@ class CakeEmailTest extends CakeTestCase {
 	}
 
 /**
+ * testSendAttachment method
+ *
+ * @return void
+ */
+	public function testSendAttachment() {
+		$this->CakeEmail->reset();
+		$this->CakeEmail->transport('debug');
+		DebugTransport::$includeAddresses = false;
+
+		$this->CakeEmail->from('cake@cakephp.org');
+		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+		$this->CakeEmail->subject('My title');
+		$this->CakeEmail->config(array());
+		$this->CakeEmail->attachments(array(WWW_ROOT . 'index.php'));
+		$this->CakeEmail->send('body');
+		$this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"index.php\""));
+
+		$this->CakeEmail->attachments(array('my.file.txt' => WWW_ROOT . 'index.php'));
+		$this->CakeEmail->send('body');
+		$this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"my.file.txt\""));
+
+		$this->CakeEmail->attachments(array('file.txt' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain')));
+		$this->CakeEmail->send('body');
+		$this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"file.txt\""));
+
+		$this->CakeEmail->attachments(array('file.txt' => array('file' => WWW_ROOT . 'index.php', 'mimetype' => 'text/plain', 'contentId' => 'a1b1c1')));
+		$this->CakeEmail->send('body');
+		$this->assertTrue((bool)strpos(DebugTransport::$lastEmail, "Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-ID: <a1b1c1>\r\nContent-Disposition: inline; filename=\"file.txt\""));
+	}
+
+/**
  * testDeliver method
  *
  * @return void