Webklex/laravel-imap

With outlook mail servers, the charset shouldn't be send with the imap_search

tkayfun opened this issue · 7 comments

Hi Webklex,

Firstly, thanks for the great package!

I encountered some problems today with the package, which is actually an edge case..

With every mayor mail server besides Microsofts (outlook) imap servers, the charset shouldn't be send with the imap search. For some reason, if we send the default UTF-8 charset with the imap_search, every search criteria besides ALL doesn't work.. If I leave it blank, every search criteria works :)

For myself I added a check if it is a microsoft account (@outlook.com / @hotmail.com), than the charset shouldn't be given to the imap_search, otherwise I am using the UTF-8 charset. If I didn't do this, I couldn't use search criteria like UNSEEN, SEEN, etc :)

For myself I did something like this;

Define somewhere logical (for me I implemented in the Folder class) an CONST with common microsoft domains;

CONST MICROSOFT_DOMAINS = [
        'outlook.com',
        'hotmail.com'
];

In the searchMessages function;

I tried it with setting the $charset = NIL, but it really shouldn't be passed when doing an imap_search.

.........
$query = trim($query);

if(in_array(substr(strrchr($this->getClient()->username, "@"), 1), self::MICROSOFT_DOMAINS)) {
    $availableMessages = imap_search($this->getClient()->getConnection(), $query, SE_UID);
} else {
    $availableMessages = imap_search($this->getClient()->getConnection(), $query, SE_UID, $charset);
}

.........

I'd like to hear from you, if you approve this approach I'll make a PR for you, otherwise I'd like to hear what your approach would be! 👍 :-)

Hi @tayfunkayahan ,
the default $charset value is actually null according to the official php imap_search() documentation.

So setting $charset to NULL should perfectly work..

Folder::searchMessages(array $where, $fetch_options = null, $fetch_body = true, NULL);

I wouldn't like the idea to perform an unnecessary (unless I' using a microsoft domain) array lookup every time I call the search method. I think it's fair to implement the logic outside if necessary :)

Instead I would like to add it to the known issue section and link it to this issue as well as the future wiki.

If I'm wrong and the majority is actually using microsoft related email addresses the $charset parameter could also be set to null in a breaking version change (2.*). But I honestly doupt that this is the case :)

Best regards

Hi @Webklex,

Thanks for your response.

I know, the PHP documentation says that it is null. imap_search has actually $charset = NIL, but when I try to pass NULL it really doesn't work. But when I totally remove the variable and set nothing for the charset it is working like a charm. So when I keep the 4rd argument empty of imap_search it is working like a charm. This BTW only happens with microsoft domains 🤦‍♂️

Did you actually try it with a Microsoft domain? Because I also tried on different environments and created different new accounts. For now it's not a that huge of problem, but that's because I just kept the 4rd argument empty in searchMessages. Running PHP 7.1.7 BTW.

True that, an extra array lookup is actually unnecessary in the library itself but if this problem really occurs with everyone with a microsoft account than it would be handy, or maybe like you said put it somewhere in the known issues so people know about this :-)

UPDATE:
Even this piece of code doesn't work;
$availableMessages = imap_search($this->getClient()->getConnection(), $query, SE_UID, null);
Even if I hard code null as 4rd parameter in imap_search it doesn't work, so I guess it is a bug in the imap_search mechanism of PHP itself?

UPDATE 2:
It is actually a known issue; barbushin/php-imap#128

@tayfunkayahan please update to the latest version. You can now set the charset to null. If however the charset is null it won't be set anymore:

if($this->getCharset() === null){
    $available_messages = imap_search($this->getClient()->getConnection(), $this->getRawQuery(), SE_UID);
}else{
    $available_messages = imap_search($this->getClient()->getConnection(), $this->getRawQuery(), SE_UID, $this->getCharset());
}

@Webklex thnx for the update! should work perfectly now!

We are using the following code:

$folder = $client->getFolder('INBOX');
$folder->query()->unseen()->leaveUnread()->get();

The following error uccurs when trying to fetch messages from outlook.office365.com server:
[BADCHARSET (US-ASCII)] The specified charset is not supported.

It looks like we need somehow to set charset to null when executing the query. Is it possible?

Hi @freescout-helpdesk ,
yes it is posiible:

/** @var \Webklex\IMAP\Folder $folder */
/** @var \Webklex\IMAP\Message $message */
$message = $folder->query(null)->get()->first();

Folder::query() Folder::search() Folder::messages() can be parsed a desired charset. UTF-8 ist the default. However by setting it to null, the charset wont be set on imap_search() and therefor prevent this error.

Best regards