Skip to content

Commit

Permalink
Determine MIME type of attachments automatically
Browse files Browse the repository at this point in the history
Add cross-platform, multibyte-safe pathinfo replacement and use it
  • Loading branch information
Synchro committed Apr 25, 2013
1 parent 78cefc6 commit 72f41f1
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 9 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* Support for do_verp
* Fix bug in CRAM-MD5 AUTH
* Propagate debug output option to SMTP class (@Reblutus)
* Determine MIME type of attachments automatically
* Add cross-platform, multibyte-safe pathinfo repalcement and use it

## Version 5.2.6 (April 11th 2013)
* Reflect move to PHPMailer GitHub organisation at https://github.com/PHPMailer/PHPMailer
Expand Down
98 changes: 89 additions & 9 deletions class.phpmailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1742,11 +1742,17 @@ public function TextLine($value) {
* @throws phpmailerException
* @return bool
*/
public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
public function AddAttachment($path, $name = '', $encoding = 'base64', $type = '') {
try {
if ( !@is_file($path) ) {
throw new phpmailerException($this->Lang('file_access') . $path, self::STOP_CONTINUE);
}

//If a MIME type is not specified, try to work it out from the file name
if ($type == '') {
$type = self::filenameToType($path);
}

$filename = basename($path);
if ( $name == '' ) {
$name = $filename;
Expand Down Expand Up @@ -2092,7 +2098,7 @@ public function EncodeQPphp($string, $line_max = 76, $space_conv = false) {
*/
public function EncodeQ($str, $position = 'text') {
//There should not be any EOL in the string
$pattern="";
$pattern = '';
$encoded = str_replace(array("\r", "\n"), '', $str);
switch (strtolower($position)) {
case 'phrase':
Expand Down Expand Up @@ -2133,7 +2139,11 @@ public function EncodeQ($str, $position = 'text') {
* @param string $type File extension (MIME) type.
* @return void
*/
public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = '') {
//If a MIME type is not specified, try to work it out from the file name
if ($type == '') {
$type = self::filenameToType($filename);
}
// Append to $attachment array
$this->attachment[] = array(
0 => $string,
Expand All @@ -2150,8 +2160,6 @@ public function AddStringAttachment($string, $filename, $encoding = 'base64', $t
/**
* Add an embedded attachment from a file.
* This can include images, sounds, and just about any other document type.
* Be sure to set the $type to an image type for images:
* JPEG images use 'image/jpeg', GIF uses 'image/gif', PNG uses 'image/png'.
* @param string $path Path to the attachment.
* @param string $cid Content ID of the attachment; Use this to reference
* the content when using an embedded image in HTML.
Expand All @@ -2160,13 +2168,17 @@ public function AddStringAttachment($string, $filename, $encoding = 'base64', $t
* @param string $type File MIME type.
* @return bool True on successfully adding an attachment
*/
public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {

public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '') {
if ( !@is_file($path) ) {
$this->SetError($this->Lang('file_access') . $path);
return false;
}

//If a MIME type is not specified, try to work it out from the file name
if ($type == '') {
$type = self::filenameToType($path);
}

$filename = basename($path);
if ( $name == '' ) {
$name = $filename;
Expand Down Expand Up @@ -2200,7 +2212,12 @@ public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64',
* @param string $type MIME type.
* @return bool True on successfully adding an attachment
*/
public function AddStringEmbeddedImage($string, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
public function AddStringEmbeddedImage($string, $cid, $name = '', $encoding = 'base64', $type = '') {
//If a MIME type is not specified, try to work it out from the name
if ($type == '') {
$type = self::filenameToType($name);
}

// Append to $attachment array
$this->attachment[] = array(
0 => $string,
Expand Down Expand Up @@ -2457,7 +2474,7 @@ public function MsgHTML($message, $basedir = '', $advanced = false) {
$directory = '';
}
$cid = 'cid:' . md5($url);
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$ext = self::mb_pathinfo($filename, PATHINFO_EXTENSION);
$mimeType = self::_mime_types($ext);
if ( strlen($basedir) > 1 && substr($basedir, -1) != '/') { $basedir .= '/'; }
if ( strlen($directory) > 1 && substr($directory, -1) != '/') { $directory .= '/'; }
Expand Down Expand Up @@ -2590,6 +2607,69 @@ public static function _mime_types($ext = '') {
return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
}

/**
* Try to map a file name to a MIME type, default to application/octet-stream
* @param string $filename A file name or full path, does not need to exist as a file
* @return string
* @static
*/
public static function filenameToType($filename) {
//In case the path is a URL, strip any query string before getting extension
$qpos = strpos($filename, '?');
if ($qpos !== false) {
$filename = substr($filename, 0, $qpos);
}
$pathinfo = self::mb_pathinfo($filename);
return self::_mime_types($pathinfo['extension']);
}

/**
* Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe.
* Works similarly to the one in PHP >= 5.2.0
* @link http://www.php.net/manual/en/function.pathinfo.php#107461
* @param string $path A filename or path, does not need to exist as a file
* @param integer|string $options Either a PATHINFO_* constant, or a string name to return only the specified piece, allows 'filename' to work on PHP < 5.2
* @return string|array
* @static
*/
public static function mb_pathinfo($path, $options = null) {
$ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');
$m = array();
preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $m);
if(array_key_exists(1, $m)) {
$ret['dirname'] = $m[1];
}
if(array_key_exists(2, $m)) {
$ret['basename'] = $m[2];
}
if(array_key_exists(5, $m)) {
$ret['extension'] = $m[5];
}
if(array_key_exists(3, $m)) {
$ret['filename'] = $m[3];
}
switch($options) {
case PATHINFO_DIRNAME:
case 'dirname':
return $ret['dirname'];
break;
case PATHINFO_BASENAME:
case 'basename':
return $ret['basename'];
break;
case PATHINFO_EXTENSION:
case 'extension':
return $ret['extension'];
break;
case PATHINFO_FILENAME:
case 'filename':
return $ret['filename'];
break;
default:
return $ret;
}
}

/**
* Set (or reset) Class Objects (variables)
*
Expand Down
15 changes: 15 additions & 0 deletions test/phpmailerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,21 @@ function test_Miscellaneous()
$this->Mail->CreateHeader();
$this->assertFalse($this->Mail->set('x', 'y'), 'Invalid property set succeeded');
$this->assertTrue($this->Mail->set('Timeout', 11), 'Valid property set failed');
//Test pathinfo
$a = '/mnt/files/飛兒樂 團光茫.mp3';
$q = PHPMailer::mb_pathinfo($a);
$this->assertEquals($q['dirname'], '/mnt/files', 'UNIX dirname not matched');
$this->assertEquals($q['basename'], '飛兒樂 團光茫.mp3', 'UNIX basename not matched');
$this->assertEquals($q['extension'], 'mp3', 'UNIX extension not matched');
$this->assertEquals($q['filename'], '飛兒樂 團光茫', 'UNIX filename not matched');
$this->assertEquals(PHPMailer::mb_pathinfo($a, PATHINFO_DIRNAME), '/mnt/files', 'Dirname path element not matched');
$this->assertEquals(PHPMailer::mb_pathinfo($a, 'filename'), '飛兒樂 團光茫', 'Filename path element not matched');
$a = 'c:\mnt\files\飛兒樂 團光茫.mp3';
$q = PHPMailer::mb_pathinfo($a);
$this->assertEquals($q['dirname'], 'c:\mnt\files', 'Windows dirname not matched');
$this->assertEquals($q['basename'], '飛兒樂 團光茫.mp3', 'Windows basename not matched');
$this->assertEquals($q['extension'], 'mp3', 'Windows extension not matched');
$this->assertEquals($q['filename'], '飛兒樂 團光茫', 'Windows filename not matched');
}
}

Expand Down

0 comments on commit 72f41f1

Please sign in to comment.