Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] For some emails, the body is empty #712

Open
tsschulz opened this issue Jul 10, 2023 · 3 comments
Open

[BUG] For some emails, the body is empty #712

tsschulz opened this issue Jul 10, 2023 · 3 comments
Labels
needs investigation This will be tested / debugged or checked out.

Comments

@tsschulz
Copy link

Environment (please complete the following information):

  • PHP IMAP version: 8.1
  • PHP Version: 8.1
  • Type of execution: Daemon

For some emails (seems like when they are send from Mac), the body is empty, for html and also for plain.

The used code:

$this->mail->textHtml ?? $this->mail->textPlain;

var_dump($this->mail):

object(PhpImap\IncomingMail)#7 (45) {
  ["id"]=>
  int(133)
  ["imapPath"]=>...
  }
  ["textPlain":"PhpImap\IncomingMail":private]=>
  NULL
  ["textHtml":"PhpImap\IncomingMail":private]=>
  NULL
}

Expected behavior
Email body has text in it, because in email client for the same email there is a body

@tsschulz tsschulz added the needs investigation This will be tested / debugged or checked out. label Jul 10, 2023
@bducha
Copy link

bducha commented Jul 25, 2023

I had a similar problem and I found the cause of it. Maybe it's the same thing for you :

If you look in the IncomingMail class, you can see that acessing to the textHtml and textPlain properties is done via the "magic" __get method.
If you look at it, you can see that the properties are nerver initialized until you access them. This will trigger the $data->fetch() and store the result into the properties :

/**
     * __get() is utilized for reading data from inaccessible (protected
     * or private) or non-existing properties.
     *
     * @param string $name Name of the property (eg. textPlain)
     *
     * @return string Value of the property (eg. Plain text message)
     */
    public function __get(string $name): string
    {
        $type = false;
        if ('textPlain' == $name) {
            $type = DataPartInfo::TEXT_PLAIN;
        }
        if ('textHtml' == $name) {
            $type = DataPartInfo::TEXT_HTML;
        }
        if (('textPlain' === $name || 'textHtml' === $name) && isset($this->$name)) {
            return (string) $this->$name;
        }
        if (false === $type) {
            \trigger_error("Undefined property: IncomingMail::$name");
        }
        if (!isset($this->$name)) {
            $this->$name = '';
        }
        foreach ($this->dataInfo[$type] as $data) {
            $this->$name .= \trim($data->fetch());
        }

        /** @var string */
        return $this->$name;
    } 

The thing is, if you var_dump the IncomingMail just after retrieving it, the textHtml and textPlain will be empty, because the __get() was never called :

$mail = $mailbox->getMail($mailId, $markAsSeen);
var_dump($mail); // textHtml and textPlain are null

But if you access the properties before printing the mail object, they will be defined :

$mail = $mailbox->getMail($mailId, $markAsSeen);
$textHtml = $mail->textHtml;
$textPlain = $mail->textPlain;
var_dump($mail); // textHtml and textPlain are defined with my mail body

And in my case, what was happening is that I would get all my emails and store them in an array for later, then I was iterating over multiple mailboxes, which reopened the imap stream to other mailboxes. And then when I finally finished iterating over all the mailboxes, I would try to read the textHtml/textPlain values but they where null, probably because the imap stream was already closed.

So accessing the two properties at least once just after retrieving the email did the trick for me.
I find this a bit sketchy if you ask me 😅

I hope this solves your problem !

@tsschulz
Copy link
Author

Thank you for your answer :) I tried it, but still have the same problem. And it is not on all emails, but only the ones that are send from MacBooks. From other email-clients, it is working fine.

But I'll have a look into the implementation too when I find the time for it.

@voicecode-bv
Copy link

voicecode-bv commented Nov 6, 2023

I can confirm, I'm having the same issue too. Unfortunately @bducha's suggestion didn't work for me neither.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs investigation This will be tested / debugged or checked out.
Projects
None yet
Development

No branches or pull requests

3 participants