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

getBodyHtml only returns first part of Mail #452

Open
KevinHansen23 opened this issue Jan 28, 2020 · 8 comments
Open

getBodyHtml only returns first part of Mail #452

KevinHansen23 opened this issue Jan 28, 2020 · 8 comments

Comments

@KevinHansen23
Copy link

KevinHansen23 commented Jan 28, 2020

Hi,

we've noticed the following bug:

In some cases $message->getBodyHtml() only returns the first part of a multipart/mixed message. The Sender (or Apple) has inserted inline Images between multiple HTML Parts. It is possible to receive all attachments using $message->getAttachments() (even though they aren't really inline).

The rawMessage is attached (I've shortened the base64 decoded attachments):
rawMessage.txt

Kind regards
Kevin

@KevinHansen23 KevinHansen23 changed the title getBodyHtml onyl returns first part of Mail getBodyHtml only returns first part of Mail Jan 28, 2020
@Slamdunk
Copy link
Collaborator

Hi, would you be able to reproduce the bug in a test case please?

@KevinHansen23
Copy link
Author

Hi, I'm not so sure what you need from me. Can you explain a little more please? Thanks.

@Slamdunk
Copy link
Collaborator

Would you be so kind to create a Pull-Request redacting a test case that uses your message to expose the bug you found? For example, this test case was redacted to reproduce a bug in handling GBK charset:

imap/tests/MessageTest.php

Lines 1052 to 1059 in 208a29f

public function testGbkCharsetDecoding(): void
{
$this->mailbox->addMessage($this->getFixture('gbk_charset'));
$message = $this->mailbox->getMessage(1);
static::assertSame('Hi', \trim($message->getDecodedContent()));
}

@KevinHansen23
Copy link
Author

Sorry, I'm completely new to Github. I have no Idea how I am supposed to do that.

@KevinHansen23
Copy link
Author

Hi,

I've created the pull request #454 . If I've missed something please let me know.

Kind regards
Kevin

@parijke
Copy link

parijke commented Sep 17, 2020

I've a message that return a blank html, it has 2 attachments. Does this help?
Campaña Caser Salud Otoño-Invierno 2020-2021, ¡te esperan grandes premios!.zip

@arwinvdv
Copy link
Contributor

Easy to reproduce:
When I create an email in Apple Mail and drag an PDF file in the middle of my email (so with text around) and send it, the getBodyHtml only returns the first part of the e-mail.

I fixed it with the method:

    private function getAllHtml(\Ddeboer\Imap\Message|\Ddeboer\Imap\MessageInterface $message)
    {
        $iterator = new \RecursiveIteratorIterator($message, \RecursiveIteratorIterator::SELF_FIRST);
        $htmlParts = [];
        foreach ($iterator as $part) {
            if ($message::SUBTYPE_HTML === $part->getSubtype()) {
                $htmlParts[] = $part->getDecodedContent();
            }
        }
        if (count($htmlParts) === 1) {
            return $htmlParts[0];
        }
        if (count($htmlParts) > 1) {
            $newDom = new DOMDocument();

            $newBody = '';
            $newDom->loadHTML(mb_convert_encoding(implode('', $htmlParts), 'HTML-ENTITIES', 'UTF-8'));

            $bodyTags = $newDom->getElementsByTagName('body');

            foreach ($bodyTags as $body) {
                foreach ($body->childNodes as $node) {
                    $newBody .= $newDom->saveHTML($node);
                }
            }

            $newDom = new DOMDocument();
            $newDom->loadHTML(mb_convert_encoding($newBody, 'HTML-ENTITIES', 'UTF-8'));

            return $newDom->saveHTML();
        }

        // If message has no parts and is HTML, return content of message itself.
        if ($message::SUBTYPE_HTML === $this->getSubtype()) {
            return $this->getDecodedContent();
        }

        return null;
    }

Merge body tags: https://stackoverflow.com/questions/60163537/save-multiple-html-bodies-as-one-using-domdocument

@Slamdunk
Copy link
Collaborator

@arwinvdv would you be so kind to propose a PR with your fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants