From a528129d3705d389bd01b77b7851bc7976207ec9 Mon Sep 17 00:00:00 2001 From: Sergey Linnik Date: Wed, 5 Aug 2015 01:21:36 +0300 Subject: [PATCH] Provide mime text decoder by RFC2047 Replace imap_utf8, and add decode address name --- src/Fetch/Attachment.php | 9 +++++-- src/Fetch/MIME.php | 45 +++++++++++++++++++++++++++++++ src/Fetch/Message.php | 4 +-- tests/Fetch/Test/MIMETest.php | 51 +++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 src/Fetch/MIME.php create mode 100644 tests/Fetch/Test/MIMETest.php diff --git a/src/Fetch/Attachment.php b/src/Fetch/Attachment.php index 431153f..e77984a 100644 --- a/src/Fetch/Attachment.php +++ b/src/Fetch/Attachment.php @@ -93,9 +93,9 @@ class Attachment $parameters = Message::getParametersFromStructure($structure); if (isset($parameters['filename'])) { - $this->filename = imap_utf8($parameters['filename']); + $this->setFileName($parameters['filename']); } elseif (isset($parameters['name'])) { - $this->filename = imap_utf8($parameters['name']); + $this->setFileName($parameters['name']); } $this->size = $structure->bytes; @@ -231,4 +231,9 @@ class Attachment return $result; } + + protected function setFileName($text) + { + $this->filename = MIME::decode($text, Message::$charset); + } } diff --git a/src/Fetch/MIME.php b/src/Fetch/MIME.php new file mode 100644 index 0000000..b63d72b --- /dev/null +++ b/src/Fetch/MIME.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fetch; + +/** + * This library is a wrapper around the Imap library functions included in php. + * + * @package Fetch + * @author Robert Hafner + * @author Sergey Linnik + */ +final class MIME +{ + /** + * @param string $text + * @param string $targetCharset + * + * @return string + */ + public static function decode($text, $targetCharset = 'utf-8') + { + if (null === $text) { + return null; + } + + $result = ''; + + foreach (imap_mime_header_decode($text) as $word) { + $ch = 'default' === $word->charset ? 'ascii' : $word->charset; + + $result .= iconv($ch, $targetCharset, $word->text); + } + + return $result; + } +} diff --git a/src/Fetch/Message.php b/src/Fetch/Message.php index 870c784..e382678 100755 --- a/src/Fetch/Message.php +++ b/src/Fetch/Message.php @@ -233,7 +233,7 @@ class Message return false; - $this->subject = isset($messageOverview->subject) ? imap_utf8($messageOverview->subject) : null; + $this->subject = MIME::decode($messageOverview->subject, self::$charset); $this->date = strtotime($messageOverview->date); $this->size = $messageOverview->size; @@ -674,7 +674,7 @@ class Message $currentAddress = array(); $currentAddress['address'] = $address->mailbox . '@' . $address->host; if (isset($address->personal)) { - $currentAddress['name'] = $address->personal; + $currentAddress['name'] = MIME::decode($address->personal, self::$charset); } $outputAddresses[] = $currentAddress; } diff --git a/tests/Fetch/Test/MIMETest.php b/tests/Fetch/Test/MIMETest.php new file mode 100644 index 0000000..f49a517 --- /dev/null +++ b/tests/Fetch/Test/MIMETest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fetch\Test; + +use Fetch\MIME; + +/** + * @package Fetch + * @author Robert Hafner + * @author Sergey Linnik + */ +class MIMETest extends \PHPUnit_Framework_TestCase +{ + public function decodeData() + { + return array( + array(null, null), + array('Just text', 'Just text'), + array('Keith Moore ', '=?US-ASCII?Q?Keith_Moore?= '), + array('Keld Jørn Simonsen ', '=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= '), + array('André Pirard ', '=?ISO-8859-1?Q?Andr=E9?= Pirard '), + array( + 'If you can read this you understand the example.', + '=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=' + . PHP_EOL . + '=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=' + ), + ); + } + + /** + * @dataProvider decodeData + * + * @param string $expected + * @param string $text + * @param string $charset + */ + public function testDecode($expected, $text, $charset = 'UTF-8') + { + self::assertSame($expected, MIME::decode($text, $charset)); + } +}