デコメールまとめ その2

デコメールまとめ。

携帯メールのMIMEフォーマットに対応したメール送信サンプル。
2年くらい前にやったので、情報が古くなっているかも・・・。


参考サイト

. Y-110's Wiki (携帯:デコメール)

http://php.y-110.net/wiki/index.php?%B7%C8%C2%D3%A1%A7%A5%C7%A5%B3%A5%E1%A1%BC%A5%EB

PHPでのメール送信サンプル

Y-110's WikiさんのMail_Mime_Decomailを利用させてもらっています。

docomo

Mail_mime_Decomail.phpを使用。

au

Mail_Mime_Au.php

<?php
require_once dirname(__FILE__) . "/Mail_mime_Decomail.php";

class Mail_Mime_Au extends Mail_Mime_Decomail {
    /**
     * Constructor
     */
    public function Mail_Mime_Au($crlf = "\r\n")
    {
        parent::Mail_Mime_Decomail($crlf);
    }

    /**
     * Override Mail_mime::get
     *
     * デコレーションメール(AU)のインライン画像の場合に対応
     *
     * mixed
     * ├ alternative
     * │ ├ text/plain
     * │ └ text/html
     * └ image (インライン、添付)
     */
    public function &get($build_params = null)
    {
        if (isset($build_params)) {
            while (list($key, $value) = each($build_params)) {
                $this->_build_params[$key] = $value;
            }
        }

        if (!empty($this->_html_images) AND isset($this->_htmlbody)) {
            foreach ($this->_html_images as $value) {
                $regex = '#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' . preg_quote($value['name'], '#') .
                         '\3#';
                $rep = '\1\2=\3cid:' . $value['cid'] .'\3';
                $this->_htmlbody = preg_replace($regex, $rep,
                                       $this->_htmlbody
                                   );
            }
        }

        $null        = null;
        $attachments = !empty($this->_parts)                ? true : false;
        $html_images = !empty($this->_html_images)          ? true : false;
        $html        = !empty($this->_htmlbody)             ? true : false;
        $text        = (!$html AND !empty($this->_txtbody)) ? true : false;

        switch (true) {
        // デコメール本文のみ
        case $html AND !$attachments AND !$html_images:
            $message =& $this->_addMixedPart();
            if (isset($this->_txtbody)) {
                $alt =& $this->_addAlternativePart($message);
                $this->_addTextPart($alt, $this->_txtbody);
                $this->_addHtmlPart($alt);
            } else {
                return false;
            }
            break;
        // デコメール本文とインライン画像
        case $html AND !$attachments AND $html_images:
            $message =& $this->_addMixedPart();
            if (isset($this->_txtbody)) {
                $alt =& $this->_addAlternativePart($message);
                $this->_addTextPart($alt, $this->_txtbody);
                $this->_addHtmlPart($alt);
            } else {
                return false;
            }
            for ($i = 0; $i < count($this->_html_images); $i++) {
                $this->_addHtmlImagePart($message, $this->_html_images[$i]);
            }
            break;
        // デコメール本文と添付画像
        case $html AND $attachments AND !$html_images:
            $message =& $this->_addMixedPart();
            if (isset($this->_txtbody)) {
                $alt =& $this->_addAlternativePart($message);
                $this->_addTextPart($alt, $this->_txtbody);
                $this->_addHtmlPart($alt);
            } else {
                return false;
            }
            for ($i = 0; $i < count($this->_parts); $i++) {
                $this->_addAttachmentPart($message, $this->_parts[$i]);
            }
            break;
        // デコメール本文と添付画像とインライン画像
        case $html AND $attachments AND $html_images:
            $message =& $this->_addMixedPart();
            if (isset($this->_txtbody)) {
                $alt =& $this->_addAlternativePart($message);
                $this->_addTextPart($alt, $this->_txtbody);
                $this->_addHtmlPart($alt);
            } else {
                return false;
            }
            for ($i = 0; $i < count($this->_html_images); $i++) {
                $this->_addHtmlImagePart($message, $this->_html_images[$i]);
            }
            for ($i = 0; $i < count($this->_parts); $i++) {
                $this->_addAttachmentPart($message, $this->_parts[$i]);
            }
            break;

        default:
            // setHTMLBody されていないとデコメールとみなさずエラー
            return false;
        }

        if (isset($message)) {
            $output = $message->encode();
            $this->_headers = array_merge($this->_headers,
                                          $output['headers']);
            return $output['body'];

        } else {
            return false;
        }
    }
}
?>
softbank

Mail_Mime_Sb.php

<?php
require_once dirname(__FILE__) . "/Mail_mime_Decomail.php";

class Mail_Mime_Sb extends Mail_Mime_Decomail {
    /**
     * Constructor
     */
    public function Mail_Mime_Sb($crlf = "\r\n")
    {
        parent::Mail_Mime_Decomail($crlf);
    }

    /**
     * Override Mail_mime::get
     *
     * デコレーションメール(softbank)のインライン画像の場合に対応
     *
     * related
     * ├ alternative
     * │ ├ text/plain
     * │ └ text/html
     * └ image (インライン、添付)
     */
    public function &get($build_params = null)
    {
        if (isset($build_params)) {
            while (list($key, $value) = each($build_params)) {
                $this->_build_params[$key] = $value;
            }
        }

        if (!empty($this->_html_images) AND isset($this->_htmlbody)) {
            foreach ($this->_html_images as $value) {
                $regex = '#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' . preg_quote($value['name'], '#') .
                         '\3#';
                $rep = '\1\2=\3cid:' . $value['cid'] .'\3';
                $this->_htmlbody = preg_replace($regex, $rep,
                                       $this->_htmlbody
                                   );
            }
        }

        $null        = null;
        $attachments = !empty($this->_parts)                ? true : false;
        $html_images = !empty($this->_html_images)          ? true : false;
        $html        = !empty($this->_htmlbody)             ? true : false;
        $text        = (!$html AND !empty($this->_txtbody)) ? true : false;

        switch (true) {
        // デコメール本文のみ
        case $html AND !$attachments AND !$html_images:
            $message =& $this->_addRelatedPart($null);
            if (isset($this->_txtbody)) {
                $alt =& $this->_addAlternativePart($message);
                $this->_addTextPart($alt, $this->_txtbody);
                $this->_addHtmlPart($alt);
            } else {
                return false;
            }
            break;
        // デコメール本文とインライン画像
        case $html AND !$attachments AND $html_images:
            $message =& $this->_addRelatedPart($null);
            if (isset($this->_txtbody)) {
                $alt =& $this->_addAlternativePart($message);
                $this->_addTextPart($alt, $this->_txtbody);
                $this->_addHtmlPart($alt);
            } else {
                return false;
            }
            for ($i = 0; $i < count($this->_html_images); $i++) {
                $this->_addHtmlImagePart($message, $this->_html_images[$i]);
            }
            break;
        // デコメール本文と添付画像
        case $html AND $attachments AND !$html_images:
            $message =& $this->_addRelatedPart($null);
            if (isset($this->_txtbody)) {
                $alt =& $this->_addAlternativePart($message);
                $this->_addTextPart($alt, $this->_txtbody);
                $this->_addHtmlPart($alt);
            } else {
                return false;
            }
            for ($i = 0; $i < count($this->_parts); $i++) {
                $this->_addAttachmentPart($message, $this->_parts[$i]);
            }
            break;
        // デコメール本文と添付画像とインライン画像
        case $html AND $attachments AND $html_images:
            $message =& $this->_addRelatedPart($null);
            if (isset($this->_txtbody)) {
                $alt =& $this->_addAlternativePart($message);
                $this->_addTextPart($alt, $this->_txtbody);
                $this->_addHtmlPart($alt);
            } else {
                return false;
            }
            for ($i = 0; $i < count($this->_html_images); $i++) {
                $this->_addHtmlImagePart($message, $this->_html_images[$i]);
            }
            for ($i = 0; $i < count($this->_parts); $i++) {
                $this->_addAttachmentPart($message, $this->_parts[$i]);
            }
            break;

        default:
            // setHTMLBody されていないとデコメールとみなさずエラー
            return false;
        }

        if (isset($message)) {
            $output = $message->encode();
            $this->_headers = array_merge($this->_headers,
                                          $output['headers']);
            return $output['body'];

        } else {
            return false;
        }
    }
}
?>
送信サンプル

Mail_Mime_factory.php

<?php
require_once('Mail.php');
require_once('Mail/mime.php');
require_once dirname(__FILE__) . "/Mail_mime_Decomail.php";
require_once dirname(__FILE__) . "/Mail_mime_Au.php";
require_once dirname(__FILE__) . "/Mail_mime_Sb.php";

class Mail_Mime_factory {
    const MAIL_TYPE_PC       = 0;
    const MAIL_TYPE_DOCOMO   = 1;
    const MAIL_TYPE_AU       = 2;
    const MAIL_TYPE_SOFTBANK = 3;
    const MAIL_TYPE_EMOBILE  = 4;

    public static $mail_types = array(self::MAIL_TYPE_PC, self::MAIL_TYPE_DOCOMO, self::MAIL_TYPE_AU, self::MAIL_TYPE_SOFTBANK);
    
    /**
     * Constructor
     */
    private function __construct()
    {
    }

    public static function create($type, $crlf = "\r\n") {
        switch($type) {
            case self::MAIL_TYPE_DOCOMO:
                return new Mail_mime_Decomail($crlf);

            case self::MAIL_TYPE_AU:
                return new Mail_mime_Au($crlf);

            case self::MAIL_TYPE_SOFTBANK:
            case self::MAIL_TYPE_EMOBILE:
                return new Mail_mime_Sb($crlf);

            default:
                return new Mail_mime_PC($crlf);
        }
    }
}
?>


・送信コード

send_sample.php

<?
    require_once(dirname(__FILE__)."/Mail_Mime_factory.php");

    // imodeメール
    $mime = Mail_Mime_factory::create(Mail_Mime_factory::MAIL_TYPE_DOCOMO, "\r\n");

    $mime->setTXTBody("メール送信テスト");   // プレーンテキストメール本文
    $mime->setHTMLBody('<HTML><HEAD><META http-equiv="content-type" content="text/html; charset=shift-jis"></HEAD><BODY><B>メール送信テスト</B><BR><IMG src="cid:1301543257@149"><BR></BODY></HTML>');  // HTMLメール本文

    // インライン画像添付
    $mime->addHTMLImage(
        "/tmp/attach/sample.jpg",    // 添付ファイルパス
        "image/gif",                 // 添付ファイルタイプ
        "sample.jpg",                // 添付ファイル名
        true,                        // 添付ファイル指定種別。true:ファイルのパス、false:バイナリイメージ
        "1301542347@149");           // HTMLメールで指定するCID

    // ヘッダ情報
    $hdrs['From']         = "from@exsample.com";
    $hdrs['Sender']       = "sender@example.com";
    $hdrs['Subject']      = "サブジェクト";
    $hdrs['To']           = "to@excample.com";

    // 出力用パラメータ
    $build_param["html_charset"] = "shift-jis";
    $build_param["text_charset"] = "shift-jis";
    $build_param["head_charset"] = "shift-jis";

    $body = $mime->get( $build_param );   // MIME変換
    $hdrs = $mime->headers($hdrs);        // MIMEヘッダ

    // SMTPで送信
    $smtp_params['host']  = "localhost";
    $smtp_params['port']  = 25;
    //$smtp_params['debug'] = true;       // デバッグフラグ
    
    $smtp = Mail::factory('smtp',  $smtp_params );
    $smtp->send("to@excample.com", $hdrs, $body);
?>