Coder Social home page Coder Social logo

webklex / php-imap Goto Github PK

View Code? Open in Web Editor NEW
293.0 13.0 138.0 780 KB

PHP-IMAP is a wrapper for common IMAP communication without the need to have the php-imap module installed / enabled. The protocol is completely integrated and therefore supports IMAP IDLE operation and the "new" oAuth authentication process as well.

Home Page: https://www.php-imap.com

License: MIT License

PHP 100.00%
php-imap imap-library imap-client php imap

php-imap's Introduction

IMAP Library for PHP

Latest release on Packagist Latest prerelease on Packagist Software License Total Downloads Hits Discord Snyk

Description

PHP-IMAP is a wrapper for common IMAP communication without the need to have the php-imap module installed / enabled. The protocol is completely integrated and therefore supports IMAP IDLE operation and the "new" oAuth authentication process as well. You can enable the php-imap module in order to handle edge cases, improve message decoding quality and is required if you want to use legacy protocols such as pop3.

Official documentation: php-imap.com

Laravel wrapper: webklex/laravel-imap

Discord: discord.gg/rd4cN9h6

Table of Contents

Documentations

Compatibility

Version PHP 5.6 PHP 7 PHP 8
v5.x / / X
v4.x / X X
v3.x / X /
v2.x X X /
v1.x X / /

Basic usage example

This is a basic example, which will echo out all Mails within all imap folders and will move every message into INBOX.read. Please be aware that this should not be tested in real life and is only meant to give an impression on how things work.

use Webklex\PHPIMAP\ClientManager;

require_once "vendor/autoload.php";

$cm = new ClientManager('path/to/config/imap.php');

/** @var \Webklex\PHPIMAP\Client $client */
$client = $cm->account('account_identifier');

//Connect to the IMAP Server
$client->connect();

//Get all Mailboxes
/** @var \Webklex\PHPIMAP\Support\FolderCollection $folders */
$folders = $client->getFolders();

//Loop through every Mailbox
/** @var \Webklex\PHPIMAP\Folder $folder */
foreach($folders as $folder){

    //Get all Messages of the current Mailbox $folder
    /** @var \Webklex\PHPIMAP\Support\MessageCollection $messages */
    $messages = $folder->messages()->all()->get();
    
    /** @var \Webklex\PHPIMAP\Message $message */
    foreach($messages as $message){
        echo $message->getSubject().'<br />';
        echo 'Attachments: '.$message->getAttachments()->count().'<br />';
        echo $message->getHTMLBody();
        
        //Move the current Message to 'INBOX.read'
        if($message->move('INBOX.read') == true){
            echo 'Message has been moved';
        }else{
            echo 'Message could not be moved';
        }
    }
}

Sponsors

elb-BIT Feline

Testing

To run the tests, please execute the following command:

composer test

Quick-Test / Static Test

To disable all test which require a live mailbox, please copy the phpunit.xml.dist to phpunit.xml and adjust the configuration:

<php>
    <env name="LIVE_MAILBOX" value="false"/>
</php>

Full-Test / Live Mailbox Test

To run all tests, you need to provide a valid imap configuration.

To provide a valid imap configuration, please copy the phpunit.xml.dist to phpunit.xml and adjust the configuration:

<php>
    <env name="LIVE_MAILBOX" value="true"/>
    <env name="LIVE_MAILBOX_DEBUG" value="true"/>
    <env name="LIVE_MAILBOX_HOST" value="mail.example.local"/>
    <env name="LIVE_MAILBOX_PORT" value="993"/>
    <env name="LIVE_MAILBOX_VALIDATE_CERT" value="false"/>
    <env name="LIVE_MAILBOX_QUOTA_SUPPORT" value="true"/>
    <env name="LIVE_MAILBOX_ENCRYPTION" value="ssl"/>
    <env name="LIVE_MAILBOX_USERNAME" value="[email protected]"/>
    <env name="LIVE_MAILBOX_PASSWORD" value="foobar"/>
</php>

The test account should not contain any important data, as it will be deleted during the test. Furthermore, the test account should be able to create new folders, move messages and should not be used by any other application during the test.

It's recommended to use a dedicated test account for this purpose. You can use the provided Dockerfile to create an imap server used for testing purposes.

Build the docker image:

cd .github/docker

docker build -t php-imap-server .

Run the docker image:

docker run --name imap-server -p 993:993 --rm -d php-imap-server

Stop the docker image:

docker stop imap-server

Known issues

Error Solution
Kerberos error: No credentials cache file found (try running kinit) (...) Uncomment "DISABLE_AUTHENTICATOR" inside your config and use the legacy-imap protocol

Support

If you encounter any problems or if you find a bug, please don't hesitate to create a new issue. However, please be aware that it might take some time to get an answer. Off-topic, rude or abusive issues will be deleted without any notice.

If you need commercial support, feel free to send me a mail at [email protected].

A little notice

If you write source code in your issue, please consider to format it correctly. This makes it so much nicer to read
and people are more likely to comment and help :)

```php

echo 'your php code...';

```

will turn into:

echo 'your php code...'; 

Features & pull requests

Everyone can contribute to this project. Every pull request will be considered, but it can also happen to be declined.
To prevent unnecessary work, please consider to create a feature issue
first, if you're planning to do bigger changes. Of course, you can also create a new feature issue if you're just wishing a feature ;)

Change log

Please see CHANGELOG for more information what has changed recently.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

php-imap's People

Contributors

amorebietakoudala avatar dastobbel avatar didi1357 avatar dwalczyk avatar ferrisbuellers avatar hellosebastian avatar hhniao avatar interlinked1 avatar latypoff avatar laurent-rizer avatar magiczne avatar max13 avatar neekthenook avatar netpok avatar oliver-holz avatar olliescase avatar peanut24 avatar pwoszczyk avatar rogerb87 avatar rskrzypczak avatar sazanof avatar scuba323 avatar shacky avatar shuergab avatar slauta avatar spanjeta avatar sulgie-eitea avatar szymekjanaczek avatar thin-k-design avatar webklex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-imap's Issues

mb_decode_mimeheader() fails on emails with multiple references

Describe the bug
I'm using laravel however this seems to be a php-imap issue so I will post it here. The connection used was gmail with the settings described in the wiki (app-password)

mb_decode_mimeheader() expects parameter 1 to be string, array given
on src/Header.php  private function decode($value)
on line 388

I have traced the issue back to 'References:' raw header

unknown

On normal emails, there is only one reference but some emails can have a hierarchy of emails in them so it picks up multiple references. This causes the public function rfc822_parse_headers($raw_headers) on line 171 to parse 'References:' as an array rather than a string.

To Reproduce
Steps to reproduce the behavior:

  1. use gmail connection (app password)
$client->connect();
       return $client->getFolders('folder name')->messages()->all()->get();
  1. emails with multiple references will fail on mb_decode_mimeheader()

Desktop / Server (please complete the following information):

  • OS: macos 10.15.7 (19H2)
  • PHP: 7.4.13

Additional context
This only happens when an email contains multiple 'References:' on a single reference the behaviour is normal with out any issues.

Error in Attachment::__construct

Describe the bug
Call to undefined function Webklex\PHPIMAP\config()
I think this function is from laravel

To Reproduce
Steps to reproduce the behavior:
If message is with attachment this error comes out.

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop / Server (please complete the following information):

  • OS: [e.g. iOS]
  • PHP: [e.g. 5.5.9]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Bugs with credentials

This's my code
image
Just forgot username & password I'd replace to null for cap picture
when run and check connect()
I got this in my console
image
and here my view
image

Outlook connection setup failed

        $client = Client::make([
            'host' => 'outlook.office365.com',
            'port' => 993,
            'encryption' => 'ssl',
            'validate_cert' => true,
            'username' => '[email protected]',
            'password' => 'abz',
            'protocol' => 'imap'
        ]);

working fine

   $client = Client::make([
            'host' => 'outlook.office365.com',
            'port' => 993,
            'encryption' => 'ssl',
           'validate_cert' => true,
            'username' => '[email protected]',
            'password' => 'AccessToken',
            'protocol' => 'imap',
           'authentication' => "oauth",
        ]);

return connection setup failed

Microsoft OAuth 2.0 Authorization

  "accessTokenResponseBody": {
    "token_type": "Bearer",
    "scope": "User.Read openid profile IMAP.AccessAsUser.All POP.AccessAsUser.All SMTP.Send",
    "expires_in": 3600,
    "ext_expires_in": 3600,
    "access_token": "AccessToken",
    "refresh_token": "RefreshToken",
    "id_token": "IdToken"
  },
  "token": "Token",
  "refreshToken": "refreshToken",
  "expiresIn": 3600,
  "id": "11111",
  "nickname": null,
  "name": "Zubair",
  "email": "[email protected]",
  "avatar": null,
  "user": {
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
    "displayName": "Zubair",
    "surname": "Zubair",
    "givenName": "Zubair",
    "id": "11111",
    "userPrincipalName": "[email protected]",
    "businessPhones": [
      
    ],
    "jobTitle": null,
    "mail": null,
    "mobilePhone": null,
    "officeLocation": null,
    "preferredLanguage": null
  },
  "businessPhones": [
    
  ],
  "displayName": "Zubair",
  "givenName": "Zubair",
  "jobTitle": null,
  "mail": null,
  "mobilePhone": null,
  "officeLocation": null,
  "preferredLanguage": null,
  "surname": "Zubair",
  "userPrincipalName": "[email protected]"
}

Remember:for google oauth working fine only issue with Microsoft

camel_case() problem

When using php-imap in a standalone php script/app you get camel_case() or snake_case() errors because seems those are laravel specific methods

leaveUnread seems to mark all messages as unread / removing the seen flag

I have recently updated the package from v1.4 -> v.2.2

In v1.4 I had this code to get mailbox folder messages:

$oClient->getFolder($_folder)->setFetchFlags(true)->setFetchBody(true)->leaveUnread()
->limit($messages_per_page, $highest_page)->get();

I have updated the syntax for v2

$oClient->getFolder($_folder)->query()->whereAll()->setFetchFlags(true)->setFetchBody(true)->leaveUnread()
->limit($messages_per_page, $highest_page)->get();

The problem is, that this now marks all messages as unread. It seems to remove the seen flag. For example: If I have 3 unseen messages and 7 seen messages in the INBOX folder and the above code is executed I will have 10 unseen messages.

in_reply_to treated as an iterable object, but its not

Describe the bug
Kinda two bugs in one:

  1. In src/Header.php:475 the Header::parseAddresses($list) function requires the given $list to be an iterable object, in the case of the "in_reply_to" header, this will only happen if there was an ongoing discussion based on one mail.
    The more common case (probably?) is that it references the one mail on which the current mail responds to.

  2. In src/Header.php:460 the Header::extractAddresses($header) function wants to parse the in_reply_to header key as an email address, but it should not be a valid email address per RFC, it should be a message identifier, see :
    https://tools.ietf.org/html/rfc2822
    3.6.4. Identification fields

[...]
The "In-Reply-To:" field will contain the contents of the "Message-
   ID:" field of the message to which this one is a reply (the "parent
   message").  If there is more than one parent message, then the "In-
   Reply-To:" field will contain the contents of all of the parents'
   "Message-ID:" fields.  If there is no "Message-ID:" field in any of
   the parent messages, then the new message will have no "In-Reply-To:"
   field.
[...]

Dont know if still want to parse it to an array with some selectable fields, but should work if the bug 1 is solved.

To Reproduce
have a answered mail in your inbox, try to recieve. The Mail needs to be the first answer
Expected behavior
A clear and concise description of what you expected to happen.

Desktop / Server (please complete the following information):

  • OS: ubuntu 20
  • PHP: 7.4
  • Version 2.1.11

Custom Flag

How do I assign a custom flag to a message?

Emtpy message html and text body

Hi.

when processed messages have "embedded" images, it creates a problem:

here is print_r of message

alt text

->getHtmlBody() return null,
-> getTextBody() return null,
and ->getBodies() too return null

incomplete values when php IMAP extension is not loaded

Describe the bug
When the php IMAP extension is not loaded, some header fields contain unexpected values

  • getTo() contains one address maximum
  • getCc() contains one address maximum
  • getMessageId() is empty
  • getInReplyTo() is empty

To Reproduce
extension=imap disabled in php.ini

Desktop / Server

  • OS: Windows 10
  • PHP: 7.4.9
  • "name": "webklex/laravel-imap", "version": "2.2.0"
  • "name": "webklex/php-imap", "version": "2.2.5",

Planned Updates?

It does not look like this repo is being maintained and I was wondering if you have any updates planned for the near future.

I have used your other repo laravel-imap in the past and see you update it regularly but not this one. I am currently working on a project in Laravel Lumen which is not supported by your laravel-imap so the alternative is to use this. Please let me know if you will maintain this code as well. Thanks.

Prevent spoof mail

You should add additional attributes to your code.

I've just send email with spoofed sender and look for the header:

Webklex\PHPIMAP\Header {#671 ▼
  +raw: b"""
    Return-Path: <real_sender@sender_domain.pl>
    Delivered-To: receipent@receipent_domain.pl
    Received: from h2.server.pl
    \tby h2.server.pl with LMTP
    \tid 4IDTIEUkm18ZSSkA87l24w
    \t(envelope-from <real_sender@sender_domain.pl>)
    \tfor <receipent@receipent_domain.pl>; Thu, 29 Oct 2020 21:21:25 +0100
    Return-path: <real_sender@sender_domain.pl>
    Envelope-to: receipent@receipent_domain.pl
    Delivery-date: Thu, 29 Oct 2020 21:21:25 +0100
    Received: from sender_domain.pl ([server ip])
    \tby h2.server.pl with esmtps  (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    \t(Exim 4.94)
    \t(envelope-from <real_sender@sender_domain.pl>)
    \tid 1kYEQG-00BPgD-S0
    \tfor receipent@receipent_domain.pl; Thu, 29 Oct 2020 21:21:25 +0100
    Received: by sender_domain.pl (Postfix, from userid 1000)
    \tid 57DADAB; Thu, 29 Oct 2020 21:21:23 +0100 (CET)
    DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=sender_domain.pl; s=default;
    \tt=1604002883; bh=CsZufJouWdjY/W12No6MSSMwbp0VaS8EOMGg9WptEaI=;
    \th=From:To:Subject:Date;
    \tb=v0NAncnNT/w+gInANxAkMt20ktM4LZquuwlokUmLpPyO3++8dy112olu63Dkn9L2E
    \t GwfHGqW+8f7g494UK6asUKqTx8fHxlEJbHqAiEV5QrlynSeZDFXsKvGDW8XNMFBKop
    \t sAjvp8NTUiNcA4MTbFaZ7RX15A/9d9QVEynU8MaNP2ZYKnq9J/JXgUjjMnx+FiULqf
    \t xJN/5rjwHRx7f6JQoXXUxuck6Zh4tSDiLLnDFasrSxed6sTNfnZMAggCyb1++estNk
    \t q6HNBwp85Az3ELo10RbBF/WM2FhxxFz1khncRtCyLXLUZ2lzhjan765KXpeYg7FUa9
    \t zItPWVTaTzTEg==
    From: faked_sender@sender_domain.pl
    To: receipent@receipent_domain.pl
    Subject: Zly from
    Message-Id: <20201029202123.57DADAB@sender_domain.pl>
    Date: Thu, 29 Oct 2020 21:21:01 +0100 (CET)
    Forward-Confirmed-ReverseDNS: Reverse and forward lookup success on server ip, -10 Spam score
    SPFCheck: Server passes SPF test, -30 Spam score
    X-DKIM: signer='sender_domain.pl' status='pass' reason=''
    DKIMCheck: Server passes DKIM test, -20 Spam score
    X-Spam-Score: -0.2 (/)
    """
  #attributes: array:25 [▼
    "from" => array:1 [▼
      0 => {#674 ▼
        +"mailbox": "faked_sender"
        +"host": "sender_domain.pl"
        +"personal": false
        +"mail": "faked_sender@sender_domain.pl"
        +"full": "faked_sender@sender_domain.pl"
      }
    ]
    "to" => array:1 [▼
      0 => {#673 ▼
        +"mailbox": "receipent"
        +"host": "receipent_domain.pl"
        +"personal": false
        +"mail": "receipent@receipent_domain.pl"
        +"full": "receipent@receipent_domain.pl"
      }
    ]
    "reply_to" => array:1 [▼
      0 => {#675 ▼
        +"mailbox": "faked_sender"
        +"host": "sender_domain.pl"
        +"personal": false
        +"mail": "faked_sender@sender_domain.pl"
        +"full": "faked_sender@sender_domain.pl"
      }
    ]
    "sender" => array:1 [▼
      0 => {#676 ▼
        +"mailbox": "faked_sender"
        +"host": "sender_domain.pl"
        +"personal": false
        +"mail": "faked_sender@sender_domain.pl"
        +"full": "faked_sender@sender_domain.pl"
      }
    ]
    "subject" => "Bad from example"
    "message_id" => "20201029202123.57DADAB@sender_domain.pl"
    "date" => Carbon\Carbon @1604002861 {#677 ▶}
    "return-path" => "<real_sender@sender_domain.pl>"
    "delivered-to" => "receipent@receipent_domain.pl"
    "received" => "by sender_domain.pl (Postfix, from userid 1000) id 57DADAB"
    "envelope-to" => "receipent@receipent_domain.pl"
    "delivery-date" => "Thu, 29 Oct 2020 21:21:25 +0100"
    "dkim-signature" => array:9 [▶]
    "message-id" => "<20201029202123.57DADAB@sender_domain.pl>"
    "forward-confirmed-reversedns" => "Reverse and forward lookup success on server ip, -10 Spam score"
    "spfcheck" => "Server passes SPF test, -30 Spam score"
    "x-dkim" => "signer='sender_domain.pl' status='pass' reason=''"
    "dkimcheck" => "Server passes DKIM test, -20 Spam score"
    "x-spam-score" => "-0.2 (/)"
    "x-spam-report" => array:21 [▶]
    "spamtally" => "Final spam score: -61"
    "toaddress" => "receipent@receipent_domain.pl"
    "fromaddress" => "faked_sender@sender_domain.pl"
    "reply_toaddress" => "faked_sender@sender_domain.pl"
    "senderaddress" => "faked_sender@sender_domain.pl"
  ]
  #config: array:9 [▶]
  +fallback_encoding: "UTF-8"
}

Atrribute sender detected fake data.
Maili server detected in Return-Path and envelope-from position real sender. In attributes envelope-from doesn't exist. Can you add this?

https://en.wikipedia.org/wiki/Email_spoofing

"webklex/php-imap": "^2.2",
php 7.4.11
debian 9.13

Incorrect parsing of Boundary

Structure::getBoundary uses incorrect regex.
$boundary = $this->header->find("/boundary\=\"?(.*)\"?/");

I have a header which contains:

Content-Type: multipart/related;
	boundary="_004_DBAPR05MB6871D506604AD447C496F0EBE4140DBAPR05MB6871eurp_";
	type="multipart/alternative"

And the boundary gets parsed as: 004_DBAPR05MB6871D506604AD447C496F0EBE4140DBAPR05MB6871eurp";

If you change the regex to: /boundary=\"?(.*)\"/" , it is parsed correctly, and you don't need the str_replace afterwards.

This will fix a problem where there is an inline image, and it doesn't get parsed as an attachment. (And maybe some other problems too)

body on null

I'm testing this. I connect ok, then read folder INBOX and read messages. But message has body null and getHtmlBody crash.

Moving a Mail removes original and creates a copy of another, old message

Describe the bug
While using the $message->move("someFolder, true) method i saw that the mail i wanted to move is deleted and in the target folder a old mail is duplicated.

To Reproduce
Steps to reproduce the behavior:
I realy dont know if you can reproduce this, or if thats a "messed up" mail server ...

  1. recieve a new mail , we call it $message
  2. Move $message it to ( in my case nested ) folder: from INBOX to my/target
  3. Origin Message is gone, and another message has been duplicated.

Expected behavior
see Additional for context
The correct "next_uid" should be picked and actually copy the origin mail to the folder insted of copying another mail inside the target folder... Or at least thats what i think should happen, dont know the "COPY" command of imap - need to check it

Desktop / Server (please complete the following information):

  • OS: ubuntu 20
  • PHP: 7.4
  • Version 2.1.12

Additional context

My logging:

[somewhere in my mail handling job]
\Log::debug(print_r(['origin message ' => $message], true)); //[0]
$message->move('my/target');

src/Message.php :661

    public function copy($folder) {
        $this->client->openFolder($this->folder_path);
        \Log::debug(print_r(['copy status of inbox ' => $this->client->getConnection()->examineFolder($this->folder_path)], true)); //[1]
        $status = $this->client->getConnection()->examineFolder($folder);
        /** @var Folder $folder */
        $folder = $this->client->getFolder($folder);
        if (isset($status["uidnext"]) && $folder !== null) {
            \Log::debug(print_r(['copy status' => $status], true)); //[2]
            \Log::debug(print_r(['uid' => $this->uid], true)); //[3]
            $next_uid = $status["uidnext"];
            if ($this->client->getConnection()->copyMessage($folder->path, $this->msgn) == true) {
                $this->client->openFolder($folder->path);
                $message_num = $this->client->getConnection()->getMessageNumber($next_uid);
                \Log::debug(print_r(['message_num' => $message_num], true)); //[4]
                $message = $folder->query()->getMessage($message_num);
                $event = $this->getEvent("message", "copied");
                $event::dispatch($this, $message);
                \Log::debug(print_r(['new message ' => $message], true)); //[6]
                return $message;
            }
        }

        return null;
    }

src/Connection/Protocols/ImapProtocol.php:799

    public function copyMessage($folder, $from, $to = null) {
        $set = (int)$from;
        \Log::debug(print_r(['folder' => $folder, 'from' => $from,'to' => $to], true)); //[5]
        if ($to !== null) {
            $set .= ':' . ($to == INF ? '*' : (int)$to);
        }

        return $this->requestAndResponse('COPY', [$set, $this->escapeString($folder)], true);
    }
[0] production.DEBUG: Array( [origin message ] => Webklex\PHPIMAP\Message Object (
            [...]
            [attributes:protected] => Array
                (
                    [message_no] =>
                    [msgn] => 1
                    [msglist] => 0
                    [uid] => 726
                )
            [folder_path:protected] => INBOX
            [...]
            [header] => Webklex\PHPIMAP\Header Object (
            ...
            Message-ID: <[email protected]>
            ...
            )

[1] production.DEBUG: Array( [copy status of inbox ] => Array (
            [...]
            [exists] => 1
            [recent] => 0
            [uidvalidity] => 1597831262
            [uidnext] => 727 
        ))
[2] production.DEBUG: Array( [copy status] => Array (
            [...]
            [exists] => 154
            [recent] => 0
            [uidvalidity] => 1597831265
            [uidnext] => 156
        ))
[3] production.DEBUG: Array( [uid] => 726 )

[4] production.DEBUG: Array([message_num] => 155)

[5] production.DEBUG: Array( [folder] => my/target, [from] => 1, [to] => )

[6] production.DEBUG: Array( [move message copy] => Webklex\PHPIMAP\Message Object (
            [...]
            [attributes:protected] => Array
                (
                    [message_no] =>
                    [msgn] => 155
                    [msglist] =>
                    [uid] => 156
                )
            )
            [folder_path:protected] => my/target
            [...]
            [header] => Webklex\PHPIMAP\Header Object (
            ...
            Message-ID: <trinity-debbb0f2-9c44-4368-9839-32d5e77161d7-1598022653825@msvc-mesg-gmx123>
            ...
            )

Basic way to get message via Uid

Please be aware that these issues will be closed if inactive for more then 14 days :)
Good Evening,

I have trouble getting message via Uid using getMessage

$oClient = Client::account('default'); // defined in config/imap.php
        $oClient->connect();
        
        // get all unseen messages from folder INBOX
        $aMessage = $oClient->getFolders();

        // $message = $aMessage->query()->getMessage($uid = 7);
        foreach ($aMessage as $oMessage) {
            // do something with the message
            $message = $oMessage->query()->getMessage(7);
        }

instead getting message Uid 7 its display Uid 13 instead
PS: a bit example will help me alot

Thanks you

installation

Hi,

I tried installation with composer but I get this:

Your requirements could not be resolved to an installable set of packages.

Problem 1
- Installation request for webklex/php-imap ^0.0.3 -> satisfiable by webklex/php-imap[0.0.3].
- Conclusion: remove nesbot/carbon 2.16.0
- Conclusion: don't install nesbot/carbon 2.16.0
- webklex/php-imap 0.0.3 requires nesbot/carbon ^1.33 -> satisfiable by nesbot/carbon[1.33.0, 1.34.0, 1.34.1, 1.34.2, 1.34.3, 1.34.4, 1.35.0, 1.35.1, 1.36.0, 1.36.1, 1.36.2, 1.37.0, 1.37.1, 1.38.0, 1.38.1, 1.38.2, 1.38.3, 1.38.4, 1.39.0].
- Can only install one of: nesbot/carbon[1.33.0, 2.16.0].
- Can only install one of: nesbot/carbon[1.34.0, 2.16.0].
- Can only install one of: nesbot/carbon[1.34.1, 2.16.0].
- Can only install one of: nesbot/carbon[1.34.2, 2.16.0].
- Can only install one of: nesbot/carbon[1.34.3, 2.16.0].
- Can only install one of: nesbot/carbon[1.34.4, 2.16.0].
- Can only install one of: nesbot/carbon[1.35.0, 2.16.0].
- Can only install one of: nesbot/carbon[1.35.1, 2.16.0].
- Can only install one of: nesbot/carbon[1.36.0, 2.16.0].
- Can only install one of: nesbot/carbon[1.36.1, 2.16.0].
- Can only install one of: nesbot/carbon[1.36.2, 2.16.0].
- Can only install one of: nesbot/carbon[1.37.0, 2.16.0].
- Can only install one of: nesbot/carbon[1.37.1, 2.16.0].
- Can only install one of: nesbot/carbon[1.38.0, 2.16.0].
- Can only install one of: nesbot/carbon[1.38.1, 2.16.0].
- Can only install one of: nesbot/carbon[1.38.2, 2.16.0].
- Can only install one of: nesbot/carbon[1.38.3, 2.16.0].
- Can only install one of: nesbot/carbon[1.38.4, 2.16.0].
- Can only install one of: nesbot/carbon[1.39.0, 2.16.0].
- Installation request for nesbot/carbon (locked at 2.16.0) -> satisfiable by nesbot/carbon[2.16.0].

how do I solve this?
Thanks a lot

paginate() returns array of "true"

I don't know if I'm not using it properly, but when I use paginate() the items are just arrays of true, while with limit() I get the messages.

Here is how I use it:

$imap = new Imap(array_merge(
    $attributes,
    [
        'password' => decrypt($this->attributes['password']),
    ],
    [
        'masks' => [
            'attachment' => \Webklex\PHPIMAP\Support\Masks\AttachmentMask::class,
            'message' => \Webklex\PHPIMAP\Support\Masks\MessageMask::class,
        ],
    ],
));
$imap->connect();

$folders = $imap->getFolders(); // Returns a correct list
$pages = $imap->getFolderByPath('folder')->messages()->all()->paginate();
$limited = $imap->getFolderByPath('folder')->messages()->all()->limit(5)->get();

So, $pages contains 5 items which are all the value true. $limited on the other hand, contains 5 Message instances which are correct.

Am I missing something?

Connection error with Version 2.x.x

Describe the bug
As I wanted to upgrade to version 2.x.x, without changing my settings, I got a "connection failed" error.

/var/www/rvt/vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php:75

Should I stay on version 1.4.x Or does I change anything on my config.

Text/Html body fetched as attachment

Describe the bug
Text-body handled as an attachment, similiar to Commit / Issue 27

To Reproduce
Don't know how this header is set, but in my mail is one multipart part not ending...
The culprit in my case is this:
Message.php:439:

    private function fetchPart(Part $part) {
            dump('fetchPart');
        if ($part->type == IMAP::MESSAGE_TYPE_TEXT && ($part->ifdisposition == 0 || (empty($part->disposition) || !in_array(strtolower($part->disposition), ['attachment', 'inline'])) ) ) {
                dump('in first if');
dump( array( 'in_array' => in_array(($subtype = strtolower($part->subtype)), ["plain", "csv", "html"]), 'subtype' => $part->subtype, ));
dump( array( 'part->filename == null: ' => ($part->filename == null), 'filename' => $part->filename, ));
dump( array( 'part->name == null: ' => ($part->name == null), 'name' => $part->name, ));
            if ( in_array(($subtype = strtolower($part->subtype)), ["plain", "csv", "html"]) && $part->filename == null && $part->name == null) { 
         [...]
             } else {
                dump('in inner else');
                $this->fetchAttachment($part);
            }

This produces:

"fetchPart"
"in first if"
array:2 [
  "in_array" => false
  "subtype" => null
]
array:2 [
  "part->filename == null: " => true
  "filename" => null
]
array:2 [
  "part->name == null: " => true
  "name" => null
]
"in inner else"

So it gets handled as an attachment ...

Thats the "$this->header" of the corresponding part:

Webklex\PHPIMAP\Header {#1509
  +raw: "This is a multi-part message in MIME format.\r\n"
  #attributes: []
  #config: array:9 [
    "delimiter" => "/"
    "fetch" => 1
    "fetch_body" => true
    "fetch_flags" => true
    "message_key" => "id"
    "fetch_order" => "asc"
    "common_folders" => array:5 [ "root" => "INBOX", "junk" => "INBOX/Junk", "draft" => "INBOX/Drafts", "sent" => "INBOX/Sent",  "trash" => "INBOX/Trash" ]
    "open" => []
    "decoder" => array:2 [
      "message" => "utf-8"
      "attachment" => "utf-8"
    ]
  ]
  +fallback_encoding: "UTF-8"
}

it has no content type ...

Expected behavior
don't fetch that as an attachment?
Maybe treat it as: If content type is null - its not a file
Message.php:439:

    private function fetchPart(Part $part) {
        if ($part->type == IMAP::MESSAGE_TYPE_TEXT && ($part->ifdisposition == 0 || (empty($part->disposition) || !in_array(strtolower($part->disposition), ['attachment', 'inline'])) ) ) {
            if ( ($part->subtype == null || in_array(($subtype = strtolower($part->subtype)), ["plain", "csv", "html"]) ) && $part->filename == null && $part->name == null) { 
         [...]
             } else {
                $this->fetchAttachment($part);
            }

Desktop / Server (please complete the following information):

  • Ubuntu 20
  • PHP: 7.4
  • Version 2.2.2

Content-Disposition is array instead of string

Describe the bug
Got an Email, where a parsed part contains an array instead of a string in src/Message.php:437:

\Log::debug(print_r($part,true));
/*
...
    [encoding] => 3
    [ifdisposition] => 1
    [disposition] => Array
        (
            [0] => inline; filename="image001.png"; size=15474;
            [1] => creation-date="Tue, 13 Oct 2020 08:30:45 GMT";
            [2] => modification-date="Tue, 13 Oct 2020 08:30:45 GMT"
        )
    [ifdescription] => 1
...
*/
if ($part->type == IMAP::MESSAGE_TYPE_TEXT && ($part->ifdisposition == 0 || (empty($part->disposition) || !in_array(strtolower($part->disposition), ['attachment', 'inline'])) ) ) {

To Reproduce
Steps to reproduce the behavior:
Create an email where a part has a definition/Disposition like this

--limiter
Content-Type: image/png; name="image001.png"
Content-Description: image001.png
Content-Disposition: inline; filename="image001.png"; size=15474;
	creation-date="Tue, 13 Oct 2020 08:30:45 GMT";
	modification-date="Tue, 13 Oct 2020 08:30:45 GMT"
Content-ID: <[email protected]>
Content-Transfer-Encoding: base64

somebase64forimage001.png==
--limiter--

Try to recive the said mail
Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop / Server (please complete the following information):

  • OS: ubuntu 20
  • PHP: 7.4
  • Version 2.1.11

Additional context
Add any other context about the problem here.

connection setup failed

Hi,

I am trying to conenct to google:

$cm = new ClientManager();
$client = $cm->make([
	'host' => 'imap.gmail.com',
	'port' => 993,
	'encryption' => 'ssl',
	'validate_cert' => TRUE,
	'username' => '****@gmail.com',
	'password' => 'PASSWORD',
	'protocol' => 'imap'
]);
$client->connect();

Then getting error: "connection setup failed"
What did I wrong?

Thanks

Pagination empty on page 2+

$paginator = $f->query()->all()->paginate(10, 1);
return 10 emails

Page 1

$paginator = $f->query()->all()->paginate(10, 2);
on page 2 or other page .return 0 email.

page 2

Desktop / Server :

  • OS:Windows 10
  • PHP: 7.4.7
  • Version: 2.2.0

Multipart-Message Boundaries are empty

Describe the bug
Got an Email, where a parsed header contains a malformed header, so that somehow the getBoundary() method is called twice and returns the correct boundary in the first run, but a empty one in the second
src/Structure.php:99:

    public function getBoundary(){
        $tmp = $this->header->find("/boundary\=\"(.*)\"/");
        \Log::debug(print_r(["getBoundary" => $tmp], true));
        return tmp;
    }
[...]
    public function find_parts(){
        if($this->type === IMAP::MESSAGE_TYPE_MULTIPART) {
            if (($boundary = $this->getBoundary()) === null)  {
                throw new MessageContentFetchingException("no content found", 0);
            }
          
            $boundaries = [
                $boundary
            ];
            \Log::debug(print_r(["boundaries" => $boundaries], true));
            if (preg_match("/boundary\=\"(.*)\"/", $this->raw, $match) == 1) {
                if(is_array($match[1])){
                    foreach($match[1] as $matched){
                        $boundaries[] = $matched;
                    }
                }else{
                    if(!empty($match[1])) {
                        $boundaries[] = $match[1];
                    }
                }
            }
            \Log::debug(print_r(["boundaries #2" => $boundaries], true));
            $raw_parts = explode( $boundaries[0], str_replace($boundaries, $boundaries[0], $this->raw) );
            $parts = [];
[...]
Log:
[2020-10-13 13:51:30] production.DEBUG: Array( [getBoundary()] => _009_VI1PR05MB57270B55FFCF7840254D7E6F95040VI1PR05MB5727eurp_ )
[2020-10-13 13:51:30] production.DEBUG: Array( [boundaries] => Array( [0] => _009_VI1PR05MB57270B55FFCF7840254D7E6F95040VI1PR05MB5727eurp_ ))
[2020-10-13 13:51:30] production.DEBUG: Array( [boundaries #2] => Array ([0] => _009_VI1PR05MB57270B55FFCF7840254D7E6F95040VI1PR05MB5727eurp_ , [1] => _000_VI1PR05MB57270B55FFCF7840254D7E6F95040VI1PR05MB5727eurp_ ))
[2020-10-13 13:51:30] production.DEBUG: Array( [getBoundary()] => null ) 
[2020-10-13 13:51:30] production.DEBUG: Array( [boundaries] => Array([0] => null ))
[2020-10-13 13:51:30] production.DEBUG: Array( [boundaries #2] => Array([0] => null ))

To Reproduce
Steps to reproduce the behavior:
Create an email where a the Header have a definition like this

Content-Language: de-DE

Content-Type: multipart/related;

	boundary="_009_VI1PR05MB57270B55FFCF7840254D7E6F95040VI1PR05MB5727eurp_";

	type="multipart/alternative"

MIME-Version: 1.0

Try to recive the said mail
Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop / Server (please complete the following information):

  • OS: ubuntu 20
  • PHP: 7.4
  • Version 2.1.11

Additional context
Another smaller Issue was that some boundary params were set without any qoute (") markers, could be fixed with an alternation on the regex = boundary\=\"?(.*)\"?

Cert validation issues

Hi again.

I updated to 2.3.0 to try and test the issues I was having with it setting the read flag, and now I am having a new issue. When I have the validate_cert option set to true I cannot authenticate at all and get the following error. The cert is valid on the mail server. Tested with the same Dovecot based mail server and a Gmail account.

ErrorException: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed 
Next Webklex\PHPIMAP\Exceptions\ConnectionFailedException: connection failed in vendor/webklex/php-imap/src/Connection/Protocols/ImapProtocol.php:77

Notice: Undefined offset: 1

I'm trying to delete single message and im gettin error like that:

Notice: Undefined offset: 1 in vendor/webklex/php-imap/src/Events/FlagNewEvent.php (line 22).

Trace:

  1. $message->delete()
  2. $status = $this->setFlag("Deleted") - src/Message.php:715;
  3. $event::dispatch($this); - src/Message.php:759
  4. return new static(func_get_args()); - src/Events/Event.php:12
  5. $this->flag = $arguments[1]; - src/Events/FlagNewEvent.php:22

Not receiving messages on idle

Describe the bug
When using idle, I never get a response from the mail server.

To Reproduce

code:

$client = Client::make([
            'host'          => 'imap.gmail.com',
            'port'          => 993,
            'encryption'    => 'ssl',
            'validate_cert' => true ,
            'username'      => 'myemail',
            'password'      => 'mypassword',
            'protocol'      => 'imap',
        ]);

        $client->connect();

        $folder = $client->getFolder("INBOX");

        $this->info('Waiting for new messages...');
         
        $folder->idle(function($message){
            $this->info('message received');
            $this->line($message->subject);
        });

Expected behavior
idle function should display new messages

Desktop / Server (please complete the following information):

  • OS: MacOS
  • PHP: 7.3.24

Active Idle Service Stops Fetching after 30mins - 45 mins

Describe the bug
Active Idle Service running from CLI or Running Service stops Fetching after 30mins - 45 mins

Code used.

public function handle() {
    
    if (is_array($this->account)) {
        $client = Client::make($this->account);
    }else{
    
        $oClient = Client::account('default');
    }

    try {

        $client = $oClient->connect();

    } catch (ConnectionFailed $e) {
  
        Log::error($e->getMessage());
        return 1;
    }
    $message_mask = \Webklex\PHPIMAP\Support\Masks\MessageMask::class;
    $client->setDefaultMessageMask($message_mask);
    /** @var Folder $folder */
    try {
        $folder = $client->getFolder("INBOX");
     
    } catch (ConnectionFailedException $e) {
        Log::error($e->getMessage());
        return 1;
    } catch (FolderFetchingException $e) {
        Log::error($e->getMessage());
        return 1;
    }

    try {
        $folder->idle(function($message){
            $this->info($message->getSubject());
            // dump("new message", $message->subject);
        });
   
    } catch (\Exception $e) {
        Log::error($e->getMessage());
        return 1;
    }

}

Desktop / Server (please complete the following information):

  • OS: WIndows 10 / Ubuntu 20.04
  • PHP: 7.2,5
  • Version 2.2.3

Return value in the documentation

Hey :)

It would be great if documentation, like the "getTextBody" of Message::Class per example, mentionned it could return false (or just bool, but it return hardly false so...).

At first, I was not expecting this, since I saw "string" as return type.
Looking into the code, I understood why I got false, of course and I therefore wrote some code in consequence.
Or maybe... Make it return an empty string instead of false ?

Continue processing message after throwing an exception

Hello,
when using your library I have a problem with some email messages throwing Invalid message date exception. But I need to process messages like this too and for example move them in some Problem folder, or just process them with date = null. But I am not able to do so, because exception is thrown immediately after calling $messages = $folder->query()->get(). So I just can't do anything with those $messages then...

Can you help me somehow please? Is there some way around this? Not throwing exception, just return date = null?

Many thanks,
Jozef

Search orWhere

How can I perform an orWhere search for several fields at once, for example, from-to-subject-text

TNEF support

Hi everyone,

Im using the lib 2.1.8 on Laravel 8.0.2 / PHP 7.4 and an MS exchange server.
Im able to connect to the account, count the number of emails in a specific folder, but cannot get the messages. Here's the code and the stack error.

Conf imap :


$oClient = new Client([
	 'host'  => 'Server',
        'port'  => 993,
        'protocol'  => 'imap', //might also use imap, [pop3 or nntp (untested)]
        'encryption'    => 'ssl', // Supported: false, 'ssl', 'tls'
        'validate_cert' => true,
        'username' => '[email protected]',
        'password' => 'password'
	]);
'options' => [
        'delimiter' => '/',
        'fetch_body' => true,
        'fetch_flags' => true,
        'message_key' => 'list',
        'fetch_order' => 'asc',
        'open' => [
            // 'DISABLE_AUTHENTICATOR' => 'GSSAPI'
        ],
        'decoder' => [
            'message' => 'utf-8', // mimeheader
            'attachment' => 'utf-8' // mimeheader
        ]
    ]

Connect : OK
Count messages : OK
Get All messages from folder : KO

Code :

$oClient->connect();
	$oFolder = $oClient->getFolder('Orange');
	$count = $oFolder->query()->all()->count();
	$messages = $oFolder->query()->all()->get();
	echo "$count";

Error seems to append when fecthing the messages.

Capture d’écran 2020-10-08 095712

Thx,
Djey

getMessage does not work anymore with UID

I have recently updated the package from v1.4 -> v.2.2

In v1.4 I had this code to get a certain message:

$message = $oClient->getFolder($data->folder)->getMessage($data->muid, $fetch_body=false, $fetch_flags=false);

I have updated the syntax for v2

$message = $oClient->getFolder($data->folder)->query()->getMessage($msgn=$data->muid, $fetch_body=false, $fetch_flags=false);

But I get always an error: unique id not found

The UID is the position in the current folder. I check that the folder is correct. In my case $data->folder was INBOX.
I tried using the message id, but this also did not work. I tried getting the number getMessageNo, but it is null for all of my messages.

While I am here asking, what is the difference between UID and Msgn?

Bad parsing of non-standard headers leading to getFrom() returning string

Describe the bug
Message::getFrom() returns a string instead of an object for mails with such a header:

From: "Facebook" <[email protected]>
To: "…" <…>
Subject: …
Date: Fri, 1 Oct 2020 01:01:01 +0200
Message-ID: <…@facebookmail.com>
MIME-Version: 1.0
Content-Type: multipart/alternative;
	boundary="----=_NextPart_…"
X-Priority: 3
X-Mailer: ZuckMail [version 1.00]
Thread-Index: …==
X-Facebook: from 2401:db00:321c:e0b:face:0:170:0 ([MTI3LjAuMC4x]) 
	by www.facebook.com with HTTPS (ZuckMail);
X-Facebook-Notify: msg; from=123456789012345; t=cid.c.…:…; mailid=…
X-FACEBOOK-PRIORITY: 0
X-Auto-Response-Suppress: All

To Reproduce
Steps to reproduce the behavior:

  1. Fetch a mail like the above one
    // […]
    $folders = $c->getFolders();
    foreach ($folders as $folder) {
        $msgs = $folder->messages();
        $msgs = $msgs->setFetchBody(false);
        $mails = $msgs->all()->get();
        foreach ($mails as $mail) {
            var_dump($mail->getFrom());
  2. you'll get
    string(15) "123456789012345"

Expected behavior

[0]=>
  object(stdClass)#1234 (5) {
    ["personal"]=>
    string(35) "Facebook"
    ["mailbox"]=>
    string(5) "notification"
    ["host"]=>
    string(8) "facebookmail.com"
    ["mail"]=>
    string(14) "[email protected]"
    ["full"]=>
    string(52) "Facebook <[email protected]>"
  }
}

Desktop:

  • OS: GNU/Linux
  • PHP: 7.4.3

additional attachment with undefined name

When I am trying decode attachment with:

$message->getAttachments();

I always have additional object in item array:

0 => Webklex\PHPIMAP\Attachment {#682 ▼
      #oMessage: Webklex\PHPIMAP\Message {#664 ▶}
      #config: array:9 [▶]
      #part: Webklex\PHPIMAP\Part {#674 ▶}
      #attributes: array:9 [▼
        "content" => ""
        "type" => "text"
        "part_number" => 0
        "content_type" => null
        "id" => null
        "name" => "undefined"
        "disposition" => null
        "img_src" => null
        "size" => 0
      ]
      #mask: "Webklex\PHPIMAP\Support\Masks\AttachmentMask"
    }

why it's showing? It's showing only one time for every message with any count attachments.

Attachment name is undefined. Too long name or cyrillic?

Hi!
I'm using webklex/php-imap 2.2.0.
Protocol: imap.
I want to get attachments from letters, .zip files are being saved properly (e.g. Astronomia0091023-2020-11-05.zip),
but one letter has .xlsx file attached with name "Прокрастинация и другие методы избежать работу 2020-11-02.xlsx" and its saved like "undefined" without any extension (not even undefined.xslx).
I saw the issue #37, but it's not solving this problem. Can you help?

how can I use setFetchBody(true) in combination with leaveUnread() ?

Currently if I run something like

$folder
        ->query()
        ->leaveUnread()
        ->since(\Carbon\Carbon::now()->subWeeks(1))
        ->setFetchFlags(false)
        ->setFetchBody(true)
        ->get();

Then it will leave all messages as read. It basically ignores the leaveUnread()

If I change setFetchBody to false then it doesn't mark the messages as read, but then I also don't have access to the email body

I want to be able to read the body but still leave the messages as unread so that when viewed in webmail they still appear to be unread

I suppose I could loop through the messages, determine if they were previously unread, and then set the flag to unread again after consuming the email body, but I would have thought that the leaveUnread would be doing this by default?

Is there a better way to achieve what I am after?

I am using 2.2.5 by the way

Many thanks

Not supported cyrillic

Describe the bug
Not supported cyrillic. Subject are not displayed correctly

Expected behavior
Full display of letters with Cyrillic

$uid or $msgn?

why doesn't receiving attachments work?
i use this code:

$cm = new ClientManager();
            $imap = $cm->make([
                'host'  => '',
                'port'  => '',
                'protocol'  => 'imap', //might also use imap, [pop3 or nntp (untested)]
                'encryption'    => ''
                'validate_cert' => true,
                'username' => '',
                'password' => '',
                'authentication' => null,
            ]);
$folder = $imap->getFolder($folder_title);
$message = $folder->query()->getMessage($message_uid);
$attachments = $message->getAttachments();

and ... not work, i get error: "Webklex\PHPIMAP\Exceptions\RuntimeException: unique id not found in file "
in example doc i found

$message = $folder->query()->getMessage(**$msgn** = 1);

uid no longer necessary? How to get $msgn?

when i get message list, i use this code:

$email_list = $folder->messages()->all()->limit($limit, $page)->get();
foreach ($email_list as $key => $value) {
                        $message_uid[] = $value->getUid();
                    }

and in $message_uid i get uid.

Error with Attachement::getExtension

Describe the bug
As I call this function (on version 1.4.5), I get this error :

Class 'Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser' not found

As looking into your declaration it should : use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;

And I can't find in Symphony http-foundation/File such a class ? Maybe symphony has change this to : Beetween versions 4.x and 5.x (read here, Deprecated: https://pkp.sfu.ca/ojs/doxygen/master/html/classSymfony_1_1Component_1_1HttpFoundation_1_1File_1_1MimeType_1_1ExtensionGuesser.html)
https://symfony.com/doc/current/components/mime.html

use Symfony\Component\Mime\MimeTypes;

$mimeTypes = new MimeTypes();
$mimeType = $mimeTypes->guessMimeType('/some/path/to/image.gif');
// Guessing is not based on the file name, so $mimeType will be 'image/gif'
// only if the given file is truly a GIF image

I did the same like this which is OK, you could use this code in the function getExtension(), Warning, It return an array, so I returned the first one, I t should be tested if the array is empty, if no extension is found

$guesser = new MimeTypes();
return isset($guesser->getExtensions($this->getMimeType())[0]) ? $guesser->getExtensions($this->getMimeType())[0] : null ;

Parse more than one Received: header

I have the folowing header

Received: from com-bemdirector002.mailprotect.com ([x.x.x.x])
\tby com-bemback004.mailprotect.com (Dovecot) with LMTP id K617O9xE3F8XaAAA+HLQTg
\tfor <[email protected]>; Fri, 18 Dec 2020 06:57:49 +0100
Received: from com-bemdirector001.mailprotect.com ([x.x.x.x])
\tby com-bemdirector002.mailprotect.com (Dovecot) with LMTP id YfJnO9xE3F/NPAAAQ2+l/g
\t; Fri, 18 Dec 2020 06:57:48 +0100
Received: from com-basicem-smtp003.srv.combell-ops.net ([x.x.x.x] helo=smtp03.mailprotect.com)
\tby com-bemdirector001.mailprotect.com with esmtp (Exim 4.89)
\t(envelope-from <[email protected]>)
\tid 1kq8lw-0005bc-Q2
\tfor [email protected]; Fri, 18 Dec 2020 06:57:48 +0100
Received: from gateway.mailprotect.com (gateway.mailprotect.com [x.x.x.x])
\tby smtp03.mailprotect.com (Postfix) with ESMTP id C17C442A2B4
\tfor <[email protected]>; Fri, 18 Dec 2020 06:57:48 +0100 (CET)
Received: from localhost (localhost [x.x.x.x])
\tby gateway.mailprotect.com (Postfix) with ESMTP id AF479300F1
\tfor <[email protected]>; Fri, 18 Dec 2020 06:57:48 +0100 (CET)
X-Virus-Scanned: amavisd-new at mailprotect.com
Received: from gateway.mailprotect.com ([x.x.x.x])
\tby localhost (gateway.mailprotect.com [x.x.x.x]) (amavisd-new, port 10025)
\twith ESMTP id Uw-k-ri61xlr for <[email protected]>;
\tFri, 18 Dec 2020 06:57:48 +0100 (CET)
Received: from mx.mailprotect.com (mx.mailprotect.com [x.x.x.x])
\tby gateway.mailprotect.com (Postfix) with ESMTP id 6C6683005E
\tfor <[email protected]>; Fri, 18 Dec 2020 06:57:48 +0100 (CET)
X-Greylist: from auto-whitelisted by SQLgrey-1.8.0
Received: from 2nd-mailin.sunnyportal.com (2nd-mailin.sunnyportal.com [x.x.x.x])
\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
\t(No client certificate requested)
\tby mx.mailprotect.com (Postfix) with ESMTPS id 530F11800CB
\tfor <[email protected]>; Fri, 18 Dec 2020 06:57:48 +0100 (CET)
dkim-signature: ...
Received: from mailin.sunnyportal.com (Unknown [x.x.x.x])
\tby 2nd-mailin.sunnyportal.com with ESMTP
\t; Fri, 18 Dec 2020 06:57:46 +0100
X-Footer: c3Vubnlwb3J0YWwuY29t
Received: from sunnyportal.com ([x.x.x.x])
\tby mailin.sunnyportal.com with ESMTP;
\tFri, 18 Dec 2020 06:57:44 +0100

However, getHeader() only shows the content of one received header in the attributes

#attributes: array:23 [▼
    "from" => array:1 [▶]
    "to" => array:2 [▶]
    ...
    "received" => array:3 [▼
      0 => "from sunnyportal.com ([192.168.5.23])"
      1 => "by mailin.sunnyportal.com with ESMTP;"
      2 => "Fri, 18 Dec 2020 06:57:44 +0100"
    ]
    "x-virus-scanned" => "amavisd-new at mailprotect.com"

Would it be possible to have all the Received: headers in the received array?

[Question] Queue retrieval of all emails

In my current project, I need to constantly download a copy of every email in a folder and without necessarily changing anything on downloaded emails. Locally (in my app), I will process them.

It's up to my user to move the email, set it read or delete it (after local processing), and a folder may contain a large number of messages.

In term of connections, efficiency, calls, memory, speed, etc… Is it better to open a single connection, process emails in ascending order one by one locally, saving the already processed Message-ID (to avoid processing them twice in case of a crash), or is it better to connect once, download like 50 or 100 messages, process them and reconnect each time when necessary (if the processing implies changing a flag or moving a message) ?

Proxy support

Is there any option to be used with proxy? If can, some example would be nice :)

Not flagged Spam

Good afternoon, a question, how can I access the messages that are not marked as spam, I have tried this way but it does not return anything, and there are several emails.
$folder->search()->not_flagged('spam')->get();

I also try to assign it the spam flag and it always returns false.
$message->setFlag(['Spam']);

Also looking in the library I found this, what does it mean that it only supports those flags?
private $available_flags = ['recent', 'flagged', 'answered', 'deleted', 'seen', 'draft'];

is it possible to search for emails that contain text or text or text ?

In GMail for example I can add this to the search query:

(A job failed at https://api.mydomain.com) OR (from:support.digitalocean.com AND CPU is running HIGH) 

Basically I want to return all emails in a single query that match either one subject or another subject

Well it would certainly be great if I could go one step further as in my GMail example above and be able to get all emails that match multiple conditions such as matching one subject or another subject AND matching the from field as well

Is any of this possible or I have to run multiple queries?

Message body/attachments empty

Describe the bug
After fixing this bug #57 I get the message from the idle function. But if I want to get the body or text I get an empty response:

$message->getTextBody(); // empty
$message->getHTMLBody(); // empty

If I just loop over the messages without the idle function it works fine.

To Reproduce

$client = Client::make([
            'host'          => 'imap.gmail.com',
            'port'          => 993,
            'encryption'    => 'ssl',
            'validate_cert' => true ,
            'username'      => 'myemail',
            'password'      => 'mypassword',
            'protocol'      => 'imap',
        ]);

        $client->connect();

        $folder = $client->getFolder("INBOX");

        $this->info('Waiting for new messages...');
         
        $folder->idle(function($message){
            dump($message->getHTMLBody();
        });

Expected behavior
Get the actual body text

Dump of the message:

Webklex\PHPIMAP\Message {#1043
  -client: Webklex\PHPIMAP\Client {#24
    +connection: Webklex\PHPIMAP\Connection\Protocols\ImapProtocol {#1035
      #noun: 8
      #connection_timeout: 1200
      #debug: false
      +stream: stream resource {@706
        crypto: array:4 [
          "protocol" => "TLSv1.2"
          "cipher_name" => "ECDHE-ECDSA-AES128-GCM-SHA256"
          "cipher_bits" => 128
          "cipher_version" => "TLSv1.2"
        ]
        timed_out: false
        blocked: true
        eof: false
        stream_type: "tcp_socket/ssl"
        mode: "r+"
        unread_bytes: 0
        seekable: false
        options: array:1 [
          "ssl" => array:2 [
            "verify_peer_name" => false
            "verify_peer" => false
          ]
        ]
      }
      #cert_validation: true
    }
    +host: "imap.gmail.com"
    +port: 993
    +protocol: "imap"
    +encryption: "ssl"
    +validate_cert: true
    +username: "receiveremail"
    +password: "xxxxxxx"
    +authentication: null
    #active_folder: "INBOX"
    #default_message_mask: "Webklex\PHPIMAP\Support\Masks\AttachmentMask"
    #default_attachment_mask: "Webklex\PHPIMAP\Support\Masks\AttachmentMask"
    #default_account_config: array:8 [
      "host" => "localhost"
      "port" => 993
      "protocol" => "imap"
      "encryption" => "ssl"
      "validate_cert" => true
      "username" => ""
      "password" => ""
      "authentication" => null
    ]
    #events: array:3 [
      "message" => array:5 [
        "new" => "Webklex\IMAP\Events\MessageNewEvent"
        "moved" => "Webklex\IMAP\Events\MessageMovedEvent"
        "copied" => "Webklex\IMAP\Events\MessageCopiedEvent"
        "deleted" => "Webklex\IMAP\Events\MessageDeletedEvent"
        "restored" => "Webklex\IMAP\Events\MessageRestoredEvent"
      ]
      "folder" => array:3 [
        "new" => "Webklex\IMAP\Events\FolderNewEvent"
        "moved" => "Webklex\IMAP\Events\FolderMovedEvent"
        "deleted" => "Webklex\IMAP\Events\FolderDeletedEvent"
      ]
      "flag" => array:2 [
        "new" => "Webklex\IMAP\Events\FlagNewEvent"
        "deleted" => "Webklex\IMAP\Events\FlagDeletedEvent"
      ]
    ]
  }
  #mask: "Webklex\PHPIMAP\Support\Masks\AttachmentMask"
  #config: array:9 [
    "delimiter" => "/"
    "fetch" => 1
    "fetch_body" => true
    "fetch_flags" => true
    "message_key" => "list"
    "fetch_order" => "asc"
    "common_folders" => array:5 [
      "root" => "INBOX"
      "junk" => "INBOX/Junk"
      "draft" => "INBOX/Drafts"
      "sent" => "INBOX/Sent"
      "trash" => "INBOX/Trash"
    ]
    "open" => []
    "decoder" => array:2 [
      "message" => "utf-8"
      "attachment" => "utf-8"
    ]
  ]
  #attributes: array:4 [
    "message_no" => null
    "msgn" => 10917
    "msglist" => null
    "uid" => "13490"
  ]
  #folder_path: "INBOX"
  +fetch_options: 1
  +fetch_body: true
  +fetch_flags: true
  +header: Webklex\PHPIMAP\Header {#1040
    +raw: """
      Delivered-To: receiveremail\r\n
      Received: by 2002:a0c:ffcf:0:0:0:0:0 with SMTP id h15csp1159534qvv; Thu, 17\r\n
       Dec 2020 06:48:39 -0800 (PST)\r\n
      X-Received: by 2002:a9d:32f:: with SMTP id 44mr28912993otv.239.1608216518970;\r\n
       Thu, 17 Dec 2020 06:48:38 -0800 (PST)\r\n
      ARC-Seal: i=1; a=rsa-sha256; t=1608216518; cv=none; d=google.com;\r\n
       s=arc-20160816;\r\n
       b=vYf8P81nvevSpEt/TdemgtLzPds/2356rm2KBsxv4tGFhEHfsm8bxMBe3u8cNhI3OM\r\n
       oeyTlkrpA6KqvKGVGlx4TSo+qAhd/KnaPJTdeu3CfWWGzXh4StNlaQY+UW9bbK/gnAcP\r\n
       CKCeHQ0fycmC9uOWUQoB/OEwoqvZNVx6mQp4P6XwNwcUoZ3h0/Rv0qKPhCM/AWzw9C38\r\n
       sZcfOjqRN8I1jBUYZRdL6schUDIsa4jgYV60XzupdBf5bttdow+3yRXzUIzrFwpRF4+J\r\n
       xMC33RB1b1Oqwcl4Cd195Rzs/oIMuLHmUbfQKoR1Z7i/Ue/LLDemHsImn6a/7SFVaNxf 5HoA==\r\n
      ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\r\n
       s=arc-20160816;\r\n
       h=mime-version:subject:message-id:to:from:date:dkim-signature;\r\n
       bh=ICw+2maoEt/gHGIaZIL7G/zsFPVdXOyEGF+TVTuluKE=;\r\n
       b=RV5042RQlrfMZhyfbWeOdpZ5rqAEsuEkB5RmUq0+SWFfa1M3Uo7bcj6y8de9C0fTOS\r\n
       b6Ep0GdWup+hGGbyyCXmatxqR2lo0sBN75uGhrBQ1KHtYx+FSu7IvwURecZNTzz9qiDR\r\n
       f3lywfG8L/SgLMHyyybYVZoijNc+PTY/ceVP9XOeruUFQGYLzr/hDQioupKRe04KJW4W\r\n
       kmWfTzZF1xe7o60jZvR3k3+kwQT2ouXhwS/mJyF9uSUj4pmgiXUMn0OCJXf5vq5PPltM\r\n
       2UOTsO0fqU/+jyZqm6qg4ALtZjRxxK1UaoRnvp2V9C3NxTE2ZybEEZE2cioU555Eaokw XVPw==\r\n
      ARC-Authentication-Results: i=1; mx.google.com; dkim=pass [email protected]\r\n
       header.s=20161025 header.b=bJv5Uyci; spf=pass (google.com: domain of\r\n
       myemail designates 209.85.220.41 as permitted sender)\r\n
       smtp.mailfrom=myemail; dmarc=pass (p=NONE sp=QUARANTINE\r\n
       dis=NONE) header.from=gmail.com\r\n
      Return-Path: <myemail>\r\n
      Received: from mail-sor-f41.google.com (mail-sor-f41.google.com.\r\n
       [209.85.220.41]) by mx.google.com with SMTPS id\r\n
       b133sor1090074oif.6.2020.12.17.06.48.38 for <receiveremail> (Google\r\n
       Transport Security); Thu, 17 Dec 2020 06:48:38 -0800 (PST)\r\n
      Received-SPF: pass (google.com: domain of myemail\r\n
       designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41;\r\n
      Authentication-Results: mx.google.com; dkim=pass [email protected]\r\n
       header.s=20161025 header.b=bJv5Uyci; spf=pass (google.com: domain of\r\n
       myemail designates 209.85.220.41 as permitted sender)\r\n
       smtp.mailfrom=myemail; dmarc=pass (p=NONE sp=QUARANTINE\r\n
       dis=NONE) header.from=gmail.com\r\n
      DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\r\n
       h=date:from:to:message-id:subject:mime-version;\r\n
       bh=ICw+2maoEt/gHGIaZIL7G/zsFPVdXOyEGF+TVTuluKE=;\r\n
       b=bJv5UyciYh+EpEAXJ3h0LwALltOQFyOD2dxALo429emR/ox9YS2gV/mbo8g7oTdpR/\r\n
       DCgrmytGo2EXd7Kqv2qGND7MRX3U/3EPeXRzGl0tfDKw9L0WJ8FAiOhSksd1KjY9jCl/\r\n
       lzNDmFnYkhb2cZwM/nGuC1mmJfjgvcnauc2lcDbD6vHWUAmvw9bwvibxbyrT1KuvNheP\r\n
       MTf1MIdL5z0w5ip6WajmkNbcxjSSqWtRRrWzQi546qiTuI/9vea/SSWzJZJHkMPx4bbY\r\n
       2pQ2ezXSZ9aO4nUqiMiz55oQupGTxk+wfcqtlvO3qnSGlYMbqDAVnDXfNabrKv/Vm8sN DvvA==\r\n
      X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net;\r\n
       s=20161025;\r\n
       h=x-gm-message-state:date:from:to:message-id:subject:mime-version;\r\n
       bh=ICw+2maoEt/gHGIaZIL7G/zsFPVdXOyEGF+TVTuluKE=;\r\n
       b=mE4X56V6vILIsGpOn5p3JsZxAnT5tC/QyXufGw72KRJ5UGy5lrNIMHjxx57efMOYgo\r\n
       vP4w06DZhAz8WDIy7wrkU7tYSOO7ExPFSP8EjO2J9/2jH/ANTl7X4GUfjmjHk4bSg7Wk\r\n
       z8M3TAZjmG1GfUsp13PNJ7YINLcBA4aGAGhxibG5bIXjhKA0HbIH6hEcw7bTUv9K1XjE\r\n
       9lc2E12rwfgocWXwbJPE5HiV+plqo3p0L4f5SJwf3+iSemDYjwysjNu5FTla5bjjbOnv\r\n
       tmXm+81BXm8terfjZ0h8K7oFoPaD86yVJoqyEFdew+cUorn2w3FEc3UZ1zKGcjV7s9wN tLdw==\r\n
      X-Gm-Message-State: AOAM53288CcFQkW6m+MK9hCqmN0dwTQDLSa4y7IeMukMYZL3Z9fYJl5/\r\n
       iXaBeK6b31n74FSTF9VIWR2mwZl/CDHnng==\r\n
      X-Google-Smtp-Source: ABdhPJxolM1E1ltoLo4n52zAoZlrfEsYhvejXbSBXY9KVI29XTjabZ24YvY5xulJ++y6141ypf8PLw==\r\n
      X-Received: by 2002:a54:4603:: with SMTP id p3mr5033899oip.127.1608216518603;\r\n
       Thu, 17 Dec 2020 06:48:38 -0800 (PST)\r\n
      Return-Path: <myemail>\r\n
      Received: from [192.168.1.113] (236-123-143-136.dynamic.caiway.nl.\r\n
       [136.143.123.236]) by smtp.gmail.com with ESMTPSA id\r\n
       r15sm1116685oie.33.2020.12.17.06.48.37 for <receiveremail> (version=TLS1_2\r\n
       cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Dec 2020 06:48:38\r\n
       -0800 (PST)\r\n
      Date: Thu, 17 Dec 2020 15:48:31 +0100\r\n
      From: My Name <myemail>\r\n
      To: My Name <receiveremail>\r\n
      Message-ID: <3f17687f-6c91-47a9-b28f-f91f59d24868@Spark>\r\n
      Subject: test\r\n
      X-Readdle-Message-ID: 3f17687f-6c91-47a9-b28f-f91f59d24868@Spark\r\n
      MIME-Version: 1.0\r\n
      Content-Type: multipart/alternative; boundary="5fdb6fc4_614fd4a1_7dbc"\r\n
      \r\n
      """
    #attributes: array:24 [
      "from" => array:1 [
        0 => {#1039
          +"personal": "My Name"
          +"mailbox": "myemail"
          +"host": "gmail.com"
          +"mail": "myemail"
          +"full": "My Name <myemail>"
        }
      ]
      "to" => array:1 [
        0 => {#1038
          +"personal": "My Name"
          +"mailbox": "support"
          +"host": "companydomain"
          +"mail": "receiveremail"
          +"full": "My Name <receiveremail>"
        }
      ]
      "subject" => "test"
      "date" => Carbon\Carbon @1608216511 {#1045
        #constructedObjectId: "0000000035f157bc0000000017847527"
        #localMonthsOverflow: null
        #localYearsOverflow: null
        #localStrictModeEnabled: null
        #localHumanDiffOptions: null
        #localToStringFormat: null
        #localSerializer: null
        #localMacros: null
        #localGenericMacros: null
        #localFormatFunction: null
        #localTranslator: null
        #dumpProperties: array:3 [
          0 => "date"
          1 => "timezone_type"
          2 => "timezone"
        ]
        #dumpLocale: null
        date: 2020-12-17 15:48:31.0 +01:00
      }
      "delivered-to" => "receiveremail"
      "received" => array:5 [
        0 => "from [192.168.1.113] (236-123-143-136.dynamic.caiway.nl."
        1 => "[136.143.123.236]) by smtp.gmail.com with ESMTPSA id"
        2 => "r15sm1116685oie.33.2020.12.17.06.48.37 for <receiveremail> (version=TLS1_2"
        3 => "cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Dec 2020 06:48:38"
        4 => "-0800 (PST)"
      ]
      "x-received" => "by 2002:a54:4603:: with SMTP id p3mr5033899oip.127.1608216518603"
      "arc-seal" => array:7 [
        0 => "i=1; a=rsa-sha256; t=1608216518; cv=none; d=google.com;"
        1 => "s=arc-20160816;"
        2 => "b=vYf8P81nvevSpEt/TdemgtLzPds/2356rm2KBsxv4tGFhEHfsm8bxMBe3u8cNhI3OM"
        3 => "oeyTlkrpA6KqvKGVGlx4TSo+qAhd/KnaPJTdeu3CfWWGzXh4StNlaQY+UW9bbK/gnAcP"
        4 => "CKCeHQ0fycmC9uOWUQoB/OEwoqvZNVx6mQp4P6XwNwcUoZ3h0/Rv0qKPhCM/AWzw9C38"
        5 => "sZcfOjqRN8I1jBUYZRdL6schUDIsa4jgYV60XzupdBf5bttdow+3yRXzUIzrFwpRF4+J"
        6 => "xMC33RB1b1Oqwcl4Cd195Rzs/oIMuLHmUbfQKoR1Z7i/Ue/LLDemHsImn6a/7SFVaNxf 5HoA=="
      ]
      "arc-message-signature" => array:9 [
        0 => "i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;"
        1 => "s=arc-20160816;"
        2 => "h=mime-version:subject:message-id:to:from:date:dkim-signature;"
        3 => "bh=ICw+2maoEt/gHGIaZIL7G/zsFPVdXOyEGF+TVTuluKE=;"
        4 => "b=RV5042RQlrfMZhyfbWeOdpZ5rqAEsuEkB5RmUq0+SWFfa1M3Uo7bcj6y8de9C0fTOS"
        5 => "b6Ep0GdWup+hGGbyyCXmatxqR2lo0sBN75uGhrBQ1KHtYx+FSu7IvwURecZNTzz9qiDR"
        6 => "f3lywfG8L/SgLMHyyybYVZoijNc+PTY/ceVP9XOeruUFQGYLzr/hDQioupKRe04KJW4W"
        7 => "kmWfTzZF1xe7o60jZvR3k3+kwQT2ouXhwS/mJyF9uSUj4pmgiXUMn0OCJXf5vq5PPltM"
        8 => "2UOTsO0fqU/+jyZqm6qg4ALtZjRxxK1UaoRnvp2V9C3NxTE2ZybEEZE2cioU555Eaokw XVPw=="
      ]
      "arc-authentication-results" => array:5 [
        0 => "i=1; mx.google.com; dkim=pass [email protected]"
        1 => "header.s=20161025 header.b=bJv5Uyci; spf=pass (google.com: domain of"
        2 => "myemail designates 209.85.220.41 as permitted sender)"
        3 => "smtp.mailfrom=myemail; dmarc=pass (p=NONE sp=QUARANTINE"
        4 => "dis=NONE) header.from=gmail.com"
      ]
      "return-path" => "<myemail>"
      "received-spf" => "pass (google.com: domain of myemail designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41"
      "authentication-results" => array:5 [
        0 => "mx.google.com; dkim=pass [email protected]"
        1 => "header.s=20161025 header.b=bJv5Uyci; spf=pass (google.com: domain of"
        2 => "myemail designates 209.85.220.41 as permitted sender)"
        3 => "smtp.mailfrom=myemail; dmarc=pass (p=NONE sp=QUARANTINE"
        4 => "dis=NONE) header.from=gmail.com"
      ]
      "dkim-signature" => array:8 [
        0 => "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;"
        1 => "h=date:from:to:message-id:subject:mime-version;"
        2 => "bh=ICw+2maoEt/gHGIaZIL7G/zsFPVdXOyEGF+TVTuluKE=;"
        3 => "b=bJv5UyciYh+EpEAXJ3h0LwALltOQFyOD2dxALo429emR/ox9YS2gV/mbo8g7oTdpR/"
        4 => "DCgrmytGo2EXd7Kqv2qGND7MRX3U/3EPeXRzGl0tfDKw9L0WJ8FAiOhSksd1KjY9jCl/"
        5 => "lzNDmFnYkhb2cZwM/nGuC1mmJfjgvcnauc2lcDbD6vHWUAmvw9bwvibxbyrT1KuvNheP"
        6 => "MTf1MIdL5z0w5ip6WajmkNbcxjSSqWtRRrWzQi546qiTuI/9vea/SSWzJZJHkMPx4bbY"
        7 => "2pQ2ezXSZ9aO4nUqiMiz55oQupGTxk+wfcqtlvO3qnSGlYMbqDAVnDXfNabrKv/Vm8sN DvvA=="
      ]
      "x-google-dkim-signature" => array:9 [
        0 => "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net;"
        1 => "s=20161025;"
        2 => "h=x-gm-message-state:date:from:to:message-id:subject:mime-version;"
        3 => "bh=ICw+2maoEt/gHGIaZIL7G/zsFPVdXOyEGF+TVTuluKE=;"
        4 => "b=mE4X56V6vILIsGpOn5p3JsZxAnT5tC/QyXufGw72KRJ5UGy5lrNIMHjxx57efMOYgo"
        5 => "vP4w06DZhAz8WDIy7wrkU7tYSOO7ExPFSP8EjO2J9/2jH/ANTl7X4GUfjmjHk4bSg7Wk"
        6 => "z8M3TAZjmG1GfUsp13PNJ7YINLcBA4aGAGhxibG5bIXjhKA0HbIH6hEcw7bTUv9K1XjE"
        7 => "9lc2E12rwfgocWXwbJPE5HiV+plqo3p0L4f5SJwf3+iSemDYjwysjNu5FTla5bjjbOnv"
        8 => "tmXm+81BXm8terfjZ0h8K7oFoPaD86yVJoqyEFdew+cUorn2w3FEc3UZ1zKGcjV7s9wN tLdw=="
      ]
      "x-gm-message-state" => "AOAM53288CcFQkW6m+MK9hCqmN0dwTQDLSa4y7IeMukMYZL3Z9fYJl5/ iXaBeK6b31n74FSTF9VIWR2mwZl/CDHnng=="
      "x-google-smtp-source" => "ABdhPJxolM1E1ltoLo4n52zAoZlrfEsYhvejXbSBXY9KVI29XTjabZ24YvY5xulJ++y6141ypf8PLw=="
      "message-id" => "<3f17687f-6c91-47a9-b28f-f91f59d24868@Spark>"
      "x-readdle-message-id" => "3f17687f-6c91-47a9-b28f-f91f59d24868@Spark"
      "mime-version" => "1.0"
      "content-type" => "multipart/alternative"
      "fromaddress" => "My Name <myemail>"
      "toaddress" => "My Name <receiveremail>"
      "boundary" => "5fdb6fc4_614fd4a1_7dbc"
    ]
    #config: array:9 [
      "delimiter" => "/"
      "fetch" => 1
      "fetch_body" => true
      "fetch_flags" => true
      "message_key" => "list"
      "fetch_order" => "asc"
      "common_folders" => array:5 [
        "root" => "INBOX"
        "junk" => "INBOX/Junk"
        "draft" => "INBOX/Drafts"
        "sent" => "INBOX/Sent"
        "trash" => "INBOX/Trash"
      ]
      "open" => []
      "decoder" => array:2 [
        "message" => "utf-8"
        "attachment" => "utf-8"
      ]
    ]
    +fallback_encoding: "UTF-8"
  }
  +raw_body: null
  #structure: Webklex\PHPIMAP\Structure {#1037
    +raw: """
      --5fdb6fc4_614fd4a1_7dbc\r\n
      Content-Type: text/plain; charset="utf-8"\r\n
      Content-Transfer-Encoding: 7bit\r\n
      Content-Disposition: inline\r\n
      \r\n
      Test\r\n
      \r\n
      Met vriendelijke groet,\r\n
      My Name\r\n
      \r\n
      --5fdb6fc4_614fd4a1_7dbc\r\n
      Content-Type: text/html; charset="utf-8"\r\n
      Content-Transfer-Encoding: quoted-printable\r\n
      Content-Disposition: inline\r\n
      \r\n
      <html xmlns=3D=22http://www.w3.org/1999/xhtml=22>\r\n
      <head>\r\n
      <title></title>\r\n
      </head>\r\n
      <body>\r\n
      <div name=3D=22messageBodySection=22>\r\n
      <div dir=3D=22auto=22>Test</div>\r\n
      </div>\r\n
      <div name=3D=22messageSignatureSection=22><br />\r\n
      <p style=3D=22margin: 0px; font-stretch: normal; line-height: normal; fon=\r\n
      t-family: &quot;Helvetica Neue&quot;; color: rgb(38, 38, 38);=22>Met vrie=\r\n
      ndelijke groet,</p>\r\n
      <p style=3D=22margin: 0px; font-stretch: normal; line-height: normal; fon=\r\n
      t-family: &quot;Helvetica Neue&quot;; color: rgb(38, 38, 38);=22>Wiebe Ni=\r\n
      euwenhuis</p>\r\n
      </div>\r\n
      </body>\r\n
      </html>\r\n
      \r\n
      --5fdb6fc4_614fd4a1_7dbc--\r\n
      \r\n
      """
    -header: Webklex\PHPIMAP\Header {#1040}
    +type: 1
    +parts: array:2 [
      0 => Webklex\PHPIMAP\Part {#1047
        +raw: """
          Content-Type: text/plain; charset="utf-8"\r\n
          Content-Transfer-Encoding: 7bit\r\n
          Content-Disposition: inline\r\n
          \r\n
          Test\r\n
          \r\n
          Met vriendelijke groet,\r\n
          My Name\r\n
          \r\n
          --
          """
        +type: 0
        +content: """
          Test\r\n
          \r\n
          Met vriendelijke groet,\r\n
          My Name
          """
        +subtype: "plain"
        +charset: "utf-8"
        +encoding: 0
        +ifdisposition: true
        +disposition: "inline"
        +ifdescription: false
        +description: null
        +filename: null
        +name: null
        +id: null
        +part_number: 0
        +bytes: 50
        +content_type: "text/plain"
        -header: Webklex\PHPIMAP\Header {#1048
          +raw: """
            Content-Type: text/plain; charset="utf-8"\r\n
            Content-Transfer-Encoding: 7bit\r\n
            Content-Disposition: inline\r\n
            """
          #attributes: array:4 [
            "content-type" => "text/plain"
            "content-transfer-encoding" => "7bit"
            "content-disposition" => "inline"
            "charset" => "utf-8"
          ]
          #config: array:9 [
            "delimiter" => "/"
            "fetch" => 1
            "fetch_body" => true
            "fetch_flags" => true
            "message_key" => "list"
            "fetch_order" => "asc"
            "common_folders" => array:5 [
              "root" => "INBOX"
              "junk" => "INBOX/Junk"
              "draft" => "INBOX/Drafts"
              "sent" => "INBOX/Sent"
              "trash" => "INBOX/Trash"
            ]
            "open" => []
            "decoder" => array:2 [
              "message" => "utf-8"
              "attachment" => "utf-8"
            ]
          ]
          +fallback_encoding: "UTF-8"
        }
      }
      1 => Webklex\PHPIMAP\Part {#1049
        +raw: """
          Content-Type: text/html; charset="utf-8"\r\n
          Content-Transfer-Encoding: quoted-printable\r\n
          Content-Disposition: inline\r\n
          \r\n
          <html xmlns=3D=22http://www.w3.org/1999/xhtml=22>\r\n
          <head>\r\n
          <title></title>\r\n
          </head>\r\n
          <body>\r\n
          <div name=3D=22messageBodySection=22>\r\n
          <div dir=3D=22auto=22>Test</div>\r\n
          </div>\r\n
          <div name=3D=22messageSignatureSection=22><br />\r\n
          <p style=3D=22margin: 0px; font-stretch: normal; line-height: normal; fon=\r\n
          t-family: &quot;Helvetica Neue&quot;; color: rgb(38, 38, 38);=22>Met vrie=\r\n
          ndelijke groet,</p>\r\n
          <p style=3D=22margin: 0px; font-stretch: normal; line-height: normal; fon=\r\n
          t-family: &quot;Helvetica Neue&quot;; color: rgb(38, 38, 38);=22>Wiebe Ni=\r\n
          euwenhuis</p>\r\n
          </div>\r\n
          </body>\r\n
          </html>\r\n
          \r\n
          --
          """
        +type: 0
        +content: """
          <html xmlns=3D=22http://www.w3.org/1999/xhtml=22>\r\n
          <head>\r\n
          <title></title>\r\n
          </head>\r\n
          <body>\r\n
          <div name=3D=22messageBodySection=22>\r\n
          <div dir=3D=22auto=22>Test</div>\r\n
          </div>\r\n
          <div name=3D=22messageSignatureSection=22><br />\r\n
          <p style=3D=22margin: 0px; font-stretch: normal; line-height: normal; fon=\r\n
          t-family: &quot;Helvetica Neue&quot;; color: rgb(38, 38, 38);=22>Met vrie=\r\n
          ndelijke groet,</p>\r\n
          <p style=3D=22margin: 0px; font-stretch: normal; line-height: normal; fon=\r\n
          t-family: &quot;Helvetica Neue&quot;; color: rgb(38, 38, 38);=22>Wiebe Ni=\r\n
          euwenhuis</p>\r\n
          </div>\r\n
          </body>\r\n
          </html>
          """
        +subtype: "html"
        +charset: "utf-8"
        +encoding: 4
        +ifdisposition: true
        +disposition: "inline"
        +ifdescription: false
        +description: null
        +filename: null
        +name: null
        +id: null
        +part_number: 1
        +bytes: 588
        +content_type: "text/html"
        -header: Webklex\PHPIMAP\Header {#1050
          +raw: """
            Content-Type: text/html; charset="utf-8"\r\n
            Content-Transfer-Encoding: quoted-printable\r\n
            Content-Disposition: inline\r\n
            """
          #attributes: array:4 [
            "content-type" => "text/html"
            "content-transfer-encoding" => "quoted-printable"
            "content-disposition" => "inline"
            "charset" => "utf-8"
          ]
          #config: array:9 [
            "delimiter" => "/"
            "fetch" => 1
            "fetch_body" => true
            "fetch_flags" => true
            "message_key" => "list"
            "fetch_order" => "asc"
            "common_folders" => array:5 [
              "root" => "INBOX"
              "junk" => "INBOX/Junk"
              "draft" => "INBOX/Drafts"
              "sent" => "INBOX/Sent"
              "trash" => "INBOX/Trash"
            ]
            "open" => []
            "decoder" => array:2 [
              "message" => "utf-8"
              "attachment" => "utf-8"
            ]
          ]
          +fallback_encoding: "UTF-8"
        }
      }
    ]
    #config: array:9 [
      "delimiter" => "/"
      "fetch" => 1
      "fetch_body" => true
      "fetch_flags" => true
      "message_key" => "list"
      "fetch_order" => "asc"
      "common_folders" => array:5 [
        "root" => "INBOX"
        "junk" => "INBOX/Junk"
        "draft" => "INBOX/Drafts"
        "sent" => "INBOX/Sent"
        "trash" => "INBOX/Trash"
      ]
      "open" => []
      "decoder" => array:2 [
        "message" => "utf-8"
        "attachment" => "utf-8"
      ]
    ]
  }
  +bodies: []
  +attachments: Webklex\PHPIMAP\Support\AttachmentCollection {#1042
    #total: null
    #items: array:2 [
      0 => Webklex\PHPIMAP\Attachment {#1051
        #oMessage: Webklex\PHPIMAP\Message {#1043}
        #config: array:9 [
          "delimiter" => "/"
          "fetch" => 1
          "fetch_body" => true
          "fetch_flags" => true
          "message_key" => "list"
          "fetch_order" => "asc"
          "common_folders" => array:5 [
            "root" => "INBOX"
            "junk" => "INBOX/Junk"
            "draft" => "INBOX/Drafts"
            "sent" => "INBOX/Sent"
            "trash" => "INBOX/Trash"
          ]
          "open" => []
          "decoder" => array:2 [
            "message" => "utf-8"
            "attachment" => "utf-8"
          ]
        ]
        #part: Webklex\PHPIMAP\Part {#1047}
        #attributes: array:9 [
          "content" => """
            Test\r\n
            \r\n
            Met vriendelijke groet,\r\n
            My Name
            """
          "type" => "text"
          "part_number" => 0
          "content_type" => "text/plain"
          "id" => null
          "name" => "undefined"
          "disposition" => "inline"
          "img_src" => null
          "size" => 50
        ]
        #mask: "Webklex\PHPIMAP\Support\Masks\AttachmentMask"
      }
      1 => Webklex\PHPIMAP\Attachment {#1052
        #oMessage: Webklex\PHPIMAP\Message {#1043}
        #config: array:9 [
          "delimiter" => "/"
          "fetch" => 1
          "fetch_body" => true
          "fetch_flags" => true
          "message_key" => "list"
          "fetch_order" => "asc"
          "common_folders" => array:5 [
            "root" => "INBOX"
            "junk" => "INBOX/Junk"
            "draft" => "INBOX/Drafts"
            "sent" => "INBOX/Sent"
            "trash" => "INBOX/Trash"
          ]
          "open" => []
          "decoder" => array:2 [
            "message" => "utf-8"
            "attachment" => "utf-8"
          ]
        ]
        #part: Webklex\PHPIMAP\Part {#1049}
        #attributes: array:9 [
          "content" => """
            <html xmlns="http://www.w3.org/1999/xhtml">\r\n
            <head>\r\n
            <title></title>\r\n
            </head>\r\n
            <body>\r\n
            <div name="messageBodySection">\r\n
            <div dir="auto">Test</div>\r\n
            </div>\r\n
            <div name="messageSignatureSection"><br />\r\n
            <p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; color: rgb(38, 38, 38);">Met vriendelijke groet,</p>\r\n
            <p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; color: rgb(38, 38, 38);">My Name</p>\r\n
            </div>\r\n
            </body>\r\n
            </html>
            """
          "type" => "text"
          "part_number" => 1
          "content_type" => "text/html"
          "id" => null
          "name" => "undefined"
          "disposition" => "inline"
          "img_src" => null
          "size" => 588
        ]
        #mask: "Webklex\PHPIMAP\Support\Masks\AttachmentMask"
      }
    ]
  }
  +flags: Webklex\PHPIMAP\Support\FlagCollection {#1041
    #total: null
    #items: array:1 [
      "seen" => "Seen"
    ]
  }
  -available_flags: array:6 [
    0 => "recent"
    1 => "flagged"
    2 => "answered"
    3 => "deleted"
    4 => "seen"
    5 => "draft"
  ]
  #events: array:2 [
    "message" => array:5 [
      "new" => "Webklex\IMAP\Events\MessageNewEvent"
      "moved" => "Webklex\IMAP\Events\MessageMovedEvent"
      "copied" => "Webklex\IMAP\Events\MessageCopiedEvent"
      "deleted" => "Webklex\IMAP\Events\MessageDeletedEvent"
      "restored" => "Webklex\IMAP\Events\MessageRestoredEvent"
    ]
    "flag" => array:2 [
      "new" => "Webklex\IMAP\Events\FlagNewEvent"
      "deleted" => "Webklex\IMAP\Events\FlagDeletedEvent"
    ]
  ]
}


html body

I am trying to parse test email and have one with html body. In email client it's ok html mail, but your parser doesn't recognize properly. It's doesn't show sender too.

Message full headers:

Return-Path: <0100017554afae0e-65c7b097-c632-4a81-aba0-0983b1300228-000000@amazonses.com>
Delivered-To: receipent@email
Received: from server.email.com
    by server.email.com with LMTP
    id N8kKEpybkl/lgCwA87l24w
    (envelope-from <0100017554afae0e-65c7b097-c632-4a81-aba0-0983b1300228-000000@amazonses.com>)
    for <receipent@email>; Fri, 23 Oct 2020 11:00:12 +0200
Return-path: <0100017554afae0e-65c7b097-c632-4a81-aba0-0983b1300228-000000@amazonses.com>
Envelope-to: receipent@email
Delivery-date: Fri, 23 Oct 2020 11:00:12 +0200
Received: from a48-34.smtp-out.amazonses.com ([54.240.48.34])
    by server.email.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
    (Exim 4.94)
    (envelope-from <0100017554afae0e-65c7b097-c632-4a81-aba0-0983b1300228-000000@amazonses.com>)
    id 1kVsvf-00CEyu-Jm
    for receipent@email; Fri, 23 Oct 2020 11:00:12 +0200
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple;
    s=jbdfwjcez6foes243en2m7xftncokldr; d=pilotmail.io; t=1603443601;
    h=Date:From:Reply-To:To:Message-ID:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding;
    bh=x5tlIUXRbj7s1gxM3CNFra8jx/CX0HpLJDpRlSt2584=;
    b=QJDnIunskiGFk2HabG5hR5Ad5VPrDFsLPOSbewBxkvOjpK/iheV6hVd/a1YjAqdh
    ihcHknBI59tRcUySH5uQ+a6FJduPDItYkLrGC9BjNmEcaiU+txUUHrPDPTsPIKPcnOA
    DCZitXXwHrs2vr1f6qDBZdfvtLChNlWbhG0Y6oB4=
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple;
    s=224i4yxa5dv7c2xz3womw6peuasteono; d=amazonses.com; t=1603443601;
    h=Date:From:Reply-To:To:Message-ID:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding:Feedback-ID;
    bh=x5tlIUXRbj7s1gxM3CNFra8jx/CX0HpLJDpRlSt2584=;
    b=PEy9ba+2EBskelpszrzak2ZzKT4okwnDdSMvbkyGsD/E4WCzlwCBc2g7wswGuZ1y
    YBm3WRo7e/boW43EMxF9FGOS+i0oZJS7Vx64n2WhApMLOAaIvjpQnGIBSdJPwXxWVh8
    3LTm/SyxpnhWcxqsXK5q2ZDmPWNrh3UB6zy9eLPg=
Date: Fri, 23 Oct 2020 09:00:00 +0000
From: Damian  <[email protected]> (Pilotmail)
Reply-To: Damian  <[email protected]>
To: receipent@email
Message-ID: <0100017554afae0e-65c7b097-c632-4a81-aba0-0983b1300228-000000@email.amazonses.com>
Mime-Version: 1.0
Content-Type: multipart/alternative;
    boundary="--==_mimepart_5f929b8fb3e42_65132ab76a9181b4105281";
    charset=UTF-8
Content-Transfer-Encoding: 7bit
X-SES-Outgoing: 2020.10.23-54.240.48.34
Feedback-ID: 1.us-east-1.62FKEKNPNNwvQjVIWf53fKHL0TdoZybuoN5ycZbAYdw=:AmazonSES
Forward-Confirmed-ReverseDNS: Reverse and forward lookup success on 54.240.48.34, -10 Spam score
SPFCheck: Server passes SPF test, -30 Spam score
X-DKIM: signer='pilotmail.io' status='pass' reason=''
DKIMCheck: Server passes DKIM test, -20 Spam score
X-DKIM: signer='amazonses.com' status='pass' reason=''
X-Spam-Score: 5.6 (+++++)
X-Spam-Report: ----------------- AUTOMATYCZNY raport antySPAMowy ----------------------
    Oprogramowanie do wykrywania spamu, dziaajce na serwerze:
    *** "server.email.com" ***,
    zidentyfikowao ten email jako prawdopodobny spam. Oryginalna wiadomo
    zostaa doczona do tej, aby mona byo j przejrze, zweryfikowa lub
    zablokowa na przyszo. Jeeli masz jakie wtpliwoci, to kieruj je pod
    adres the administrator of that system
    Przegld zawartoci: Simple Transactional Email This is preheader text. Some clients
    will show this text as a preview. Hello client, 
    Szczegy analizy zawartoci: (5.6 zaliczonych, 5.0 wymaganych)
    pkt nazwa reguy krtki opis
    ---- ---------------------- -------------------------------------------
    -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2)
    [54.240.48.34 listed in wl.mailspike.net]
    0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level
    mail domains are different
    -0.0 SPF_PASS SPF: sender matches SPF record
    0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record
    0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was
    blocked. See
    http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block
    for more information.
    [URIs: pilotmail.io]
    0.0 T_KAM_HTML_FONT_INVALID BODY: Test for Invalidly Named or
    Formatted Colors in HTML
    0.1 MIME_HTML_MOSTLY BODY: Wiadomo wieloczciowa, gownie
    tekst/html MIME
    0.0 HTML_MESSAGE BODY: Wiadomo zawiera kod HTML
    0.7 MPART_ALT_DIFF BODY: HTML and text parts are different
    -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from
    author's domain
    0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily
    valid
    -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
    -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from
    envelope-from domain
    2.2 HTML_TITLE_SUBJ_DIFF No description available.
    2.5 FREEMAIL_FORGED_REPLYTO Freemail in Reply-To, but not From
X-Old-Subject:test
Subject: *****SPAM***** test
X-Spam-Status: Yes, score=5.6, +20 total spam score
SpamTally: Final spam score: -4

hasHTMLBody is empty, only getTextBody working..

$message->getBodies() value:

array:1 [▼
  "text" => """
    ----==_mimepart_5f929b8fb3e42_65132ab76a9181b4105281


    Content-Type: text/html;


     charset=UTF-8


    Content-Transfer-Encoding: quoted-printable


    


    <!DOCTYPE html>=0D


    <html>=0D


      <head>=0D


        <meta name=3D"viewport" content=3D"width=3Ddevice-width">=0D


        <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3DUTF=


    -8">=0D


        <title>Simple Transactional Email</title>=0D


        =0D


      <style>@media only screen and (max-width: 620px) {=0D


      table[class=3Dbody] h1 {=0D


        font-size: 28px !important; margin-bottom: 10px !important;=0D


      }=0D


      table[class=3Dbody] p {=0D


        font-size: 16px !important;=0D


      }=0D


      table[class=3Dbody] ul {=0D


        font-size: 16px !important;=0D


      }=0D


      table[class=3Dbody] ol {=0D


        font-size: 16px !important;=0D


      }=0D


      table[class=3Dbody] td {=0D


        font-size: 16px !important;=0D


      }=0D


      table[class=3Dbody] span {=0D


        font-size: 16px !important;=0D


      }=0D


      table[class=3Dbody] a {=0D


        font-size: 16px !important;=0D


      }=0D


      table[class=3Dbody] .wrapper {=0D


        padding: 10px !important;=0D


      }=0D


      table[class=3Dbody] .article {=0D


        padding: 10px !important;=0D


      }=0D


      table[class=3Dbody] .content {=0D


        padding: 0 !important;=0D


      }=0D


      table[class=3Dbody] .container {=0D


        padding: 0 !important; width: 100% !important;=0D


      }=0D


      table[class=3Dbody] .main {=0D


        border-left-width: 0 !important; border-radius: 0 !important; border-=


    right-width: 0 !important;=0D


      }=0D


      table[class=3Dbody] .btn table {=0D


        width: 100% !important;=0D


      }=0D


      table[class=3Dbody] .btn a {=0D


        width: 100% !important;=0D


      }=0D


      table[class=3Dbody] .img-responsive {=0D


        height: auto !important; max-width: 100% !important; width: auto !imp=


    ortant;=0D


      }=0D


    }=0D


    .ExternalClass {=0D


    width: 100%;=0D


    }=0D


    .ExternalClass {=0D


    line-height: 100%;=0D


    }=0D


    .btn-primary table td:hover {=0D


    background-color: #34495e !important;=0D


    }=0D


    .btn-primary a:hover {=0D


    background-color: #34495e !important; border-color: #34495e !important;=0D=


    


    }=0D


    </style>=0D


    </head>=0D


      <body class=3D"" style=3D"font-family: sans-serif; -webkit-font-smoothi=


    ng: antialiased; font-size: 14px; line-height: 1.4; -ms-text-size-adjust:=


     100%; -webkit-text-size-adjust: 100%; margin: 0; padding: 0;" bgcolor=3D=


    "#f6f6f6">=0D


        <span class=3D"preheader" style=3D"color: transparent; display: none;=


     height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; ms=


    o-hide: all; visibility: hidden; width: 0;">This is preheader text. Some =


    clients will show this text as a preview.</span>=0D


        <table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" class=3D"body=


    " style=3D"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rs=


    pace: 0pt; width: 100%;" bgcolor=3D"#f6f6f6">=0D


          <tr>=0D


            <td style=3D"font-family: sans-serif; font-size: 14px;" valign=3D=


    "top">=C2=A0</td>=0D


            <td class=3D"container" style=3D"font-family: sans-serif; font-si=


    ze: 14px; display: block; max-width: 580px; width: 580px; margin: 0 auto;=


     padding: 10px;" valign=3D"top">=0D


              <div class=3D"content" style=3D"box-sizing: border-box; display=


    : block; max-width: 580px; margin: 0 auto; padding: 10px;">=0D


    =0D


                <!-- START CENTERED WHITE CONTAINER -->=0D


                <table class=3D"main" style=3D"border-collapse: separate; mso=


    -table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; border-radius: 3p=


    x;" bgcolor=3D"#ffffff">=0D


    =0D


                  <!-- START MAIN CONTENT AREA -->=0D


                  <tr>=0D


                    <td class=3D"wrapper" style=3D"font-family: sans-serif; f=


    ont-size: 14px; box-sizing: border-box; padding: 20px;" valign=3D"top">=0D=


    


                      <table border=3D"0" cellpadding=3D"0" cellspacing=3D"0"=


     style=3D"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rsp=


    ace: 0pt; width: 100%;">=0D


                        <tr>=0D


                          <td style=3D"font-family: sans-serif; font-size: 14=


    px;" valign=3D"top">=0D


                            <p style=3D"font-family: sans-serif; font-size: 1=


    4px; font-weight: normal; margin: 0 0 15px;">Hello client,</p>=0D


                            <p style=3D"font-family: sans-serif; font-size: 1=


    4px; font-weight: normal; margin: 0 0 15px;">Your order ..=0D


                            \t</p>=0D


    <p style=3D"font-family: sans-serif; font-size: 14px; font-weight: normal=


    ; margin: 0 0 15px;">...</p>=0D


                            =0D


                            <table border=3D"0" cellpadding=3D"0" cellspacing=


    =3D"0" class=3D"btn btn-primary" style=3D"border-collapse: separate; mso-=


    table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border=


    -box;">=0D


                              <tbody>=0D


                                <tr>=0D


                                  <td align=3D"left" style=3D"font-family: sa=


    ns-serif; font-size: 14px; padding-bottom: 15px;" valign=3D"top">=0D


                                    <table border=3D"0" cellpadding=3D"0" cel=


    lspacing=3D"0" style=3D"border-collapse: separate; mso-table-lspace: 0pt;=


     mso-table-rspace: 0pt; width: auto;">=0D


                                      <tbody>=0D


                                        <tr>=0D


                                          <td style=3D"font-family: sans-seri=


    f; font-size: 14px; border-radius: 5px;" align=3D"center" bgcolor=3D"#349=


    8db" valign=3D"top"> <a href=3D"/public/payment/do/" target=3D"_blank" st=


    yle=3D"display: inline-block; color: #ffffff; background-color: #3498db; =


    border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decorat=


    ion: none; font-size: 14px; font-weight: bold; text-transform: capitalize=


    ; margin: 0; padding: 12px 25px; border: 1px solid #3498db;">Pay order</a=


    > </td>=0D


                                        </tr>=0D


                                      </tbody>=0D


                                    </table>=0D


                                  </td>=0D


                                </tr>=0D


                              </tbody>=0D


                            </table>=0D


                          </td>=0D


                        </tr>=0D


                      </table>=0D


                    </td>=0D


                  </tr>=0D


    =0D


                <!-- END MAIN CONTENT AREA -->=0D


                </table>=0D


    =0D


                <!-- START FOOTER -->=0D


                <div class=3D"footer" style=3D"clear: both; margin-top: 10px;=


     width: 100%;" align=3D"center">=0D


                  <table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" sty=


    le=3D"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace:=


     0pt; width: 100%;">=0D


                    <tr>=0D


                      <td class=3D"content-block" style=3D"font-family: sans-=


    serif; padding-bottom: 10px; padding-top: 10px; font-size: 12px; color: #=


    999999;" align=3D"center" valign=3D"top">=0D


                        <span class=3D"apple-link" style=3D"color: #999999; f=


    ont-size: 12px; text-align: center;"> company bla bla bla</span>=0D


                        <br> Don't like these emails? <a href=3D"https://my=


    url.pl" style=3D"text-decoration: underline; color: #999999; font-size: 1=


    2px; text-align: center;">Unsubscribe</a>.=0D


                      </td>=0D


                    </tr>=0D


                  </table>=0D


                </div>=0D


                <!-- END FOOTER -->=0D


    =0D


              <!-- END CENTERED WHITE CONTAINER -->=0D


              </div>=0D


            </td>=0D


            <td style=3D"font-family: sans-serif; font-size: 14px;" valign=3D=


    "top">=C2=A0</td>=0D


          </tr>=0D


        </table>=0D


      </body>=0D


    </html>=0D


    


    ----==_mimepart_5f929b8fb3e42_65132ab76a9181b4105281
    """
]

Bug in array_merge_recursive_distinct() function.

Hi

I think there might be a bug in the array_merge_recursive_distinct() function in ClientManager.php.

I get the following errors:

Notice: Undefined index: default in /www/html/t/imap/vendor/webklex/php-imap/src/ClientManager.php on line 200

Warning: array_merge(): Argument #1 is not an array in /www/html/t/imap/vendor/webklex/php-imap/src/ClientManager.php on line 207

The array looks malformed - print_r($config) at Line 189 in ClientManager.php gives:

Array ( [default] => default [date_format] => d-M-Y [accounts] => Array ( [gmail] => Array ( [host] => imap.gmail.com [port] => 993 [encryption] => ssl [validate_cert] => 1 [username] => [email protected] [password] => password [authentication] => imap ) ) [options] => Array ( [delimiter] => / [fetch] => 1 [fetch_body] => 1 [fetch_flags] => 1 [message_key] => list [fetch_order] => asc [common_folders] => Array ( [root] => INBOX [junk] => INBOX/Junk [draft] => INBOX/Drafts [sent] => INBOX/Sent [trash] => INBOX/Trash ) [open] => Array ( ) [decoder] => Array ( [message] => utf-8 [attachment] => utf-8 ) ) [events] => Array ( [message] => Array ( [new] => Webklex\PHPIMAP\Events\MessageNewEvent [moved] => Webklex\PHPIMAP\Events\MessageMovedEvent [copied] => Webklex\PHPIMAP\Events\MessageCopiedEvent [deleted] => Webklex\PHPIMAP\Events\MessageDeletedEvent [restored] => Webklex\PHPIMAP\Events\MessageRestoredEvent ) [folder] => Array ( [new] => Webklex\PHPIMAP\Events\FolderNewEvent [moved] => Webklex\PHPIMAP\Events\FolderMovedEvent [deleted] => Webklex\PHPIMAP\Events\FolderDeletedEvent ) [flag] => Array ( [new] => Webklex\PHPIMAP\Events\FlagNewEvent [deleted] => Webklex\PHPIMAP\Events\FlagDeletedEvent ) ) [masks] => Array ( [message] => Webklex\PHPIMAP\Support\Masks\MessageMask [attachment] => Webklex\PHPIMAP\Support\Masks\AttachmentMask ) )

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.