IMAP PHP со встроенными изображениями, не отображающими Codeigniter на локальном хосте


Я использую codeigniter и imap php, в настоящее время разрабатывающий проект xampp. По какой-то причине их встроенные изображения не отображаются.

В моей функции getBody() у меня есть этот обратный вызов

$body = preg_replace_callback(
        '/src="cid:(.*)">/Uims',
        function($m) use($email, $uid){
            //split on @
            $parts = explode('@', $m[1]);
            //replace local path with absolute path
            $img = str_replace($parts[0], '', $parts[0]);
            return "src='$img'>";
       },
    $body);

enter image description here

enter image description here

Я получаю ошибку

enter image description here

Вопрос: Как я могу убедиться, что он получает правильные изображения для текста/html-текста и т. Д.

<?php

class Email extends MY_Controller {

    private $enc;
    private $host;
    private $user;
    private $pass;
    private $mailbox;
    private $mbox;

    public function __construct() {
        parent::__construct();

        $this->enc = '/imap/ssl/novalidate-cert';
        $this->host = '****';
        $this->user = '****'; // email
        $this->pass = '****'; // Pass

        $this->mailbox = '{' . $this->host . $this->enc . '}';
        $this->mbox = imap_open($this->mailbox, $this->user, $this->pass);
    }

    public function view() {

        $this->data['message'] = $this->getBody($this->uri->segment(4));

        $this->load->view('template/common/header', $this->data);
        $this->load->view('template/common/nav', $this->data);
        $this->load->view('template/mail/view', $this->data);
        $this->load->view('template/common/footer', $this->data);

        imap_close($this->mbox);
    }

    public function getBody($uid) {
        $body = $this->get_part($uid, "TEXT/HTML");
        // if HTML body is empty, try getting text body
        if ($body == "") {
            $body = $this->get_part($uid, "TEXT/PLAIN");
        }

        $email = $this->user;

        //replace cid with full path to image
        $body = preg_replace_callback(
            '/src="cid:(.*)">/Uims',
            function($m) use($email, $uid){
                //split on @
                $parts = explode('@', $m[1]);
                //replace local path with absolute path
                $img = str_replace($parts[0], '', $parts[0]);
                return "src='$img'>";
           },
        $body);

        return trim(utf8_encode(quoted_printable_decode($body)));
    }    

    private function get_part($uid, $mimetype, $structure = false, $partNumber = false) {
        if (!$structure) {
               $structure = imap_fetchstructure($this->mbox, $uid);
        }
        if ($structure) {
            if ($mimetype == $this->get_mime_type($structure)) {
                if (!$partNumber) {
                    $partNumber = 1;
                }
                $text = imap_fetchbody($this->mbox, $uid, $partNumber, FT_PEEK);
                switch ($structure->encoding) {
                    # 7BIT
                    case 0:
                        return imap_qprint($text);
                    # 8BIT
                    case 1:
                        return imap_8bit($text);
                    # BINARY
                    case 2:
                        return imap_binary($text);
                    # BASE64
                    case 3:
                        return imap_base64($text);
                    # QUOTED-PRINTABLE
                    case 4:
                        return quoted_printable_decode($text);
                    # OTHER
                    case 5:
                        return $text;
                    # UNKNOWN
                    default:
                        return $text;
                }
           }
            // multipart
            if ($structure->type == 1) {
                foreach ($structure->parts as $index => $subStruct) {
                    $prefix = "";
                    if ($partNumber) {
                        $prefix = $partNumber . ".";
                    }
                    $data = $this->get_part($uid, $mimetype, $subStruct, $prefix . ($index + 1));
                    if ($data) {
                        return $data;
                    }
                }
            }
        }
        return false;
    }

    private function get_mime_type($structure) {
        $primaryMimetype = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER");
        if ($structure->subtype) {
           return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
        }
        return "TEXT/PLAIN";
    }

}
Author: Mr. ED, 2017-12-24

1 answers

Введение

Вы пытаетесь преобразовать электронное письмо в HTML-страницу.

Электронное письмо состоит из нескольких частей:

  1. Заголовки
  2. Текстовое электронное письмо
  3. Электронная почта на основе HTML
  4. Вложения

В заголовке вы найдете Message-ID, а также другие соответствующие метаданные.

Чтобы преобразовать электронное письмо в веб-сайт, вы должны предоставить HTML-код и вложения браузеру.

Каждая из частей имеет свой собственный заголовки. Когда у вас есть url='cid:Whatever', вам нужно посмотреть, в какой части электронного письма есть этот заголовок с идентификатором содержимого.

Отправляйте электронное письмо в качестве веб-страницы

Вам нужно найти, какая часть электронной почты содержит текст HTML. Проанализируйте его и замените URL-адрес CID для вашего http://yourhost/{emailId}, вы уже реализовали эту часть, поэтому я не буду добавлять, как это сделать здесь.

Заменить URL CID на HTML-реализацию

Это прототип, который может работать для ты.

$mailHTML="<html>All your long code here</html>";
$mailId="email.eml";
$generatePartURL=function ($messgeId, $cid) {
    return "http://myhost/".$messgeId."/".$cid; //Adapt this url according to your needs
};
$replace=function ($matches) use ($generatePartURL, $mailId) {
    list($uri, $cid) = $matches;
    return $generatePartURL($mailId, $cid);
};
$mailHTML=preg_replace_callback("/cid:([^'\" \]]*)/", $replace, $mailHTML);

Найдите деталь по CID

http://yourhost/{emailId}/{cid}

Псевдокод:

  • Загрузить электронную почту
  • Найти деталь по CID
  • Декодирование из Base64 или другой используемой кодировки (Проверьте заголовок кодирования передачи содержимого)
  • Подавать файл в качестве HTTP-ответа

В какой части есть мое изображение CID?

Повторите все части электронной почты в поисках заголовка Content-ID, соответствующего вашему значению CID.

--_part_boundery_
Content-Type: image/jpeg; name="filename.jpg"
Content-Description: filename.jpg
Content-Disposition: inline; filename="filename.jpg"; size=39619; creation-date="Thu, 28 Dec 2017 10:53:51 GMT"; modification-date="Thu, 28 Dec 2017 10:53:51 GMT"
Content-ID: <YOUR CID WILL BE HERE>
Content-Transfer-Encoding: base64

Расшифровать передачу кодирование и передача содержимого в виде обычного http-файла.

Веб-почта, реализованная на PHP

Roundcube - это веб-почта, реализованная на PHP. Вы можете посмотреть, как они это делают: https://github.com/roundcube/roundcubemail/blob/master/program/lib/Roundcube/rcube_washtml.php

Примечание: Мой код не основан на этом решении.

 1
Author: albert, 2017-12-31 18:24:50