php-imap
php-imap copied to clipboard
Support for cyrillic Windows-1251
Hi! As described at #76 we need support for subject that decoded in cyrilic Windows-1251
Subject: =?Windows-1251?B?z+7k8uLl8Obk5e3o5SDk7vHy4OLq6CDx7u7h+eXt6P8g7eAg4OTw5fEgb3BAbnBwc2Vuc29yLnJ1?=
For example you may send any mail to [email protected] and wait for response message that contains this subject
Added in Webklex\PHPIMAP\Header -> decode method
if (strpos(strtolower($value), '=?windows-1251?') !== false) { $decoder = 'iconv'; }
works fine for me
Full working example!
private function decode($value) {
if (is_array($value)) {
return $this->decodeArray($value);
}
$original_value = $value;
$decoder = $this->config['decoder']['message'];
if(strpos(strtolower($value), '=?windows-1251?') !== false) {
$decoder = 'iconv';
}
if ($value !== null) {
$is_utf8_base = $this->is_uft8($value);
if($decoder === 'utf-8' && extension_loaded('imap')) {
$value = \imap_utf8($value);
$is_utf8_base = $this->is_uft8($value);
if ($is_utf8_base) {
$value = mb_decode_mimeheader($value);
}
if ($this->notDecoded($original_value, $value)) {
$decoded_value = $this->mime_header_decode($value);
if (count($decoded_value) > 0) {
if(property_exists($decoded_value[0], "text")) {
$value = $decoded_value[0]->text;
}
}
}
}elseif($decoder === 'iconv' && $is_utf8_base) {
$value = iconv_mime_decode($value);
}elseif($decoder === 'iconv') {
$value = iconv_mime_decode($value);
}elseif($is_utf8_base){
$value = mb_decode_mimeheader($value);
}
if ($this->is_uft8($value)) {
$value = mb_decode_mimeheader($value);
}
if ($this->notDecoded($original_value, $value)) {
$value = $this->convertEncoding($original_value, $this->getEncoding($original_value));
}
}
return $value;
}
Hi @alaevka , many thanks for the followup! Would you like to create a pull request?
Otherwise i'll patch it during the next weekend :)
Best regards,
Hi @alaevka , as you might noticed, I havn't found a patch jet. It turns out to be a a bit more complicated than just "fixing" the regex :)
Best regards,
Hi @Webklex
For me part of the problem comes from divided attributes
Here are some raw attributes that should be managed (in rfc822_parse_headers() of Header.php ??) :
Content-Type: application/pdf;
name="=?UTF-8?Q?PPT_support_CS_SYDED_du_19_05_2021_VF_avec_r=c3=a9sultat_d?=
=?UTF-8?Q?es_votes=2epdf?="
Content-Type: application/pdf;
name*0*=UTF-8''Un%20mail%20%C3%A0v%C3%A9c%20un%20s%C3%B9jet%20tr%C3%A8s;
name*1*=%20long%20pour%20voir%20ce%20qu%27ca%20donne%20quand%20n%20met%20;
name*2*=boucoup%20de%20la%20donn%C3%A9e%20de%20la%20mort%20dans%20un%20en;
name*3*=droit%20qu%27on%20devrait%20p%C3%A0s.pdf
We'll continue to drill in your code because we got another mail that is not working (no attachment found while exists in rawData)
Thanks Best regards
for those who use laravel and have problems with encoding Russian headers, you can use:
private function decode($value) {//dump($value);
if (is_array($value)) {
return $this->decodeArray($value);
}
$original_value = $value;
$decoder = $this->config['decoder']['message'];
if(strpos(strtolower($value), '=?windows-1251?') !== false || strpos(strtolower($value), '=?koi8-r') !== false) {
$value = Str::replace(['=?KOI8-R?B?', '?='], '', $value);
$value = base64_decode($value); // decode base64 data
$value = iconv('koi8-r', 'UTF-8', $value); // convert source data to UTF-8
}
if ($value !== null) {
$is_utf8_base = $this->is_uft8($value);
if($decoder === 'utf-8' && extension_loaded('imap')) {
$value = \imap_utf8($value);
$is_utf8_base = $this->is_uft8($value);
if ($is_utf8_base) {
$value = mb_decode_mimeheader($value);
}
if ($this->notDecoded($original_value, $value)) {
$decoded_value = $this->mime_header_decode($value);
if (count($decoded_value) > 0) {
if(property_exists($decoded_value[0], "text")) {
$value = $decoded_value[0]->text;
}
}
}
}elseif($decoder === 'iconv' && $is_utf8_base) {
$value = iconv_mime_decode($value);
}elseif($decoder === 'iconv') {
$value = iconv_mime_decode($value);
}elseif($is_utf8_base){
$value = mb_decode_mimeheader($value);
}
if ($this->is_uft8($value)) {
$value = mb_decode_mimeheader($value);
}
if ($this->notDecoded($original_value, $value)) {
$value = $this->convertEncoding($original_value, $this->getEncoding($original_value));
}
}
return $value;
}
or rewrite one line in pure php and a regular expression
Same problem with getting attachment name or filename in UTF-8.
Sample attachment header:
Content-Type: application/pdf;
name="=?UTF-8?B?0J/RgNC40LvQvtC20LXQvdC40LUgNyAtINCh0L7Qs9C70LDRgdC40LUg?=
=?UTF-8?B?0YEg0KLQly5wZGY=?="
Content-Disposition: attachment;
filename*0*=UTF-8''%D0%9F%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8;
filename*1*=%D0%B5%20%37%20%2D%20%D0%A1%D0%BE%D0%B3%D0%BB%D0%B0%D1%81;
filename*2*=%D0%B8%D0%B5%20%D1%81%20%D0%A2%D0%97%2E%70%64%66
Content-Transfer-Encoding: base64
Result name in attachment name: undefined
Please update to v5.1 and give it another try. If you are currently using an older version below v5.0, please read the breaking changes leading up to v5.1 before upgrading.
Best regards,