ডাব্লুপি_মেল () এর মাধ্যমে মাল্টিপার্ট (পাঠ্য / এইচটিএমএল) ইমেলগুলি প্রেরণ করা সম্ভবত আপনার ডোমেনটিকে নিষিদ্ধ করবে


37

সারাংশ

ডাব্লুপি কোরে একটি ত্রুটির কারণে ডাব্লুপি_মেল ( ) এর সাথে মাল্টিপার্ট ইমেলগুলি (এইচটিএমএল / পাঠ্য) প্রেরণ করা ( স্প্যাম ফোল্ডারগুলিতে ইমেলের সম্ভাবনা হ্রাস করতে) আপনার ডোমেনটি হটমেইল (এবং অন্যান্য মাইক্রোসফ্ট ইমেলগুলি) দ্বারা অবরুদ্ধ করার সাথে বিদ্রূপাত্মকভাবে ফলাফল করবে ।

এটি একটি জটিল সমস্যা যা আমি কাউকে একটি কার্যক্ষম সমাধান খুঁজে বের করতে সহায়তা করার প্রয়াসে দুর্দান্তভাবে বিশদে ভাঙ্গার লক্ষ্য করব যা শেষ পর্যন্ত মূলত প্রয়োগ করা যেতে পারে।

এটি একটি লাভজনক পড়া হতে চলেছে। চল শুরু করি...

পোকাটি

আপনার নিউজলেটার ইমেলগুলি স্প্যাম ফোল্ডারে শেষ না হওয়া এড়াতে সর্বাধিক সাধারণ পরামর্শ হ'ল মাল্টিপার্ট বার্তা প্রেরণ।

মাল্টি-পার্ট (মাইম) বলতে একক ইমেলটিতে ইমেল বার্তার একটি এইচটিএমএল এবং পাঠ্য উভয় অংশ প্রেরণকে বোঝায়। যখন কোনও ক্লায়েন্ট কোনও মাল্টিপার্ট বার্তা পায়, এটি এইচটিএমএল রেন্ডার করতে পারলে এটি HTML সংস্করণ গ্রহণ করে, অন্যথায় এটি সরল পাঠ্য সংস্করণ উপস্থাপন করে।

এটি কাজ প্রমাণিত। জিমেইলে প্রেরণ করার সময়, আমাদের সমস্ত ইমেলগুলি স্প্যাম ফোল্ডারে অবতীর্ণ হয় যতক্ষণ না আমরা মুখ্য বার্তাগুলি মূল ইনবক্সে আসার পরে মাল্টিপার্টে পরিবর্তন করি। দুর্দান্ত জিনিস।

এখন, wp_mail () এর মাধ্যমে মাল্টিপার্ট বার্তা প্রেরণ করার সময় এটি একবারে বাউন্ডারি (কাস্টমালি সেট করা থাকলে) এবং একবার ছাড়াই কন্টেন্ট টাইপ (মাল্টিপার্ট / *) দুবার আউটপুট করে। এই আচরণের ফলে ইমেলটি কাঁচা বার্তা হিসাবে প্রদর্শিত হয় এবং সমস্ত মাইক্রোসফ্ট (হটমেল, আউটলুক, ইত্যাদি ...) সহ কিছু ইমেলগুলিতে গুণিত হয় না results

মাইক্রোসফ্ট এই বার্তাটিকে জাঙ্ক হিসাবে পতাকাঙ্কিত করবে এবং যে কয়েকটি বার্তাগুলি আসবে তা প্রাপক নিজে হাতে পতাকাঙ্কিত করবেন। দুর্ভাগ্যক্রমে , মাইক্রোসফ্ট ইমেল ঠিকানাগুলি বহুল ব্যবহৃত হয়। আমাদের গ্রাহকদের 40% এটি ব্যবহার করে।

মাইক্রোসফ্ট আমাদের সম্প্রতি একটি ইমেল এক্সচেঞ্জের মাধ্যমে এটি নিশ্চিত করেছে।

বার্তাগুলির পতাকাঙ্কণের ফলে ডোমেন সম্পূর্ণরূপে অবরুদ্ধ হয়ে যাবে । এর অর্থ হ'ল বার্তা স্প্যাম ফোল্ডারে প্রেরণ করা হবে না, এমনকি এগুলি প্রাপকের কাছে মোটেও বিতরণ করা হবে না

আমরা এখনও পর্যন্ত আমাদের মূল ডোমেনটি 3 বার অবরুদ্ধ করেছি।

যেহেতু এটি ডাব্লুপি কোরে একটি ত্রুটি, তাই প্রতিটি ডোমেন যে বহুগুণ বার্তা প্রেরণ করে তা অবরুদ্ধ করা হচ্ছে। সমস্যাটি হ'ল বেশিরভাগ ওয়েবমাস্টাররা কেন তা জানেন না। আমি আমার গবেষণাটি করার সময় এবং অন্যান্য ব্যবহারকারীদের ফোরাম ইত্যাদিতে এই বিষয়ে আলোচনা করার সময় আমি এটি নিশ্চিত করেছিলাম এর জন্য কাঁচা কোডটি অনুসন্ধান করা এবং এই ধরণের ইমেল বার্তাগুলি কীভাবে কাজ করে, যা আমরা পরের দিকে চলেছি তার একটি ভাল জ্ঞান থাকা দরকার ...

কোডে এটি ভেঙে দেওয়া যাক

একটি হটমেল / আউটলুক অ্যাকাউন্ট তৈরি করুন। তারপরে, নিম্নলিখিত কোডটি চালান:

// Set $to to an hotmail.com or outlook.com email
$to = "YourEmail@hotmail.com";

$subject = 'wp_mail testing multipart';

$message = '------=_Part_18243133_1346573420.1408991447668
Content-Type: text/plain; charset=UTF-8

Hello world! This is plain text...


------=_Part_18243133_1346573420.1408991447668
Content-Type: text/html; charset=UTF-8

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>

<p>Hello World! This is HTML...</p> 

</body>
</html>


------=_Part_18243133_1346573420.1408991447668--';

$headers = "MIME-Version: 1.0\r\n";
$headers .= "From: Foo <foo@bar.com>\r\n";
$headers .= 'Content-Type: multipart/alternative;boundary="----=_Part_18243133_1346573420.1408991447668"';


// send email
wp_mail( $to, $subject, $message, $headers );

এবং আপনি যদি ডিফল্ট সামগ্রীর প্রকারটি পরিবর্তন করতে চান তবে ব্যবহার করুন:

add_filter( 'wp_mail_content_type', 'set_content_type' );
function set_content_type( $content_type ) {
    return 'multipart/alternative';
}

এটি একাধিক বার্তা প্রেরণ করবে।

সুতরাং আপনি যদি বার্তার পুরো কাঁচা উত্সটি পরীক্ষা করেন তবে আপনি খেয়াল করবেন যে সামগ্রীটির ধরণটি একবার বাউন্ডারি ছাড়াই একবার যুক্ত করা হয়েছে:

MIME-Version: 1.0
Content-Type: multipart/alternative;
         boundary="====f230673f9d7c359a81ffebccb88e5d61=="
MIME-Version: 1.0
Content-Type: multipart/alternative; charset=

এটাই সমস্যা।

সমস্যার উত্স নিহিত pluggable.php- যদি আমরা এখানে কোথাও দেখি:

// Set Content-Type and charset
    // If we don't have a content-type from the input headers
    if ( !isset( $content_type ) )
        $content_type = 'text/plain';

    /**
     * Filter the wp_mail() content type.
     *
     * @since 2.3.0
     *
     * @param string $content_type Default wp_mail() content type.
     */
    $content_type = apply_filters( 'wp_mail_content_type', $content_type );

    $phpmailer->ContentType = $content_type;

    // Set whether it's plaintext, depending on $content_type
    if ( 'text/html' == $content_type )
        $phpmailer->IsHTML( true );

    // If we don't have a charset from the input headers
    if ( !isset( $charset ) )
        $charset = get_bloginfo( 'charset' );

    // Set the content-type and charset

    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset );

    // Set custom headers
    if ( !empty( $headers ) ) {
        foreach( (array) $headers as $name => $content ) {
            $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) );
        }

        if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) )
            $phpmailer->AddCustomHeader( sprintf( "Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) );
    }

    if ( !empty( $attachments ) ) {
        foreach ( $attachments as $attachment ) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch ( phpmailerException $e ) {
                continue;
            }
        }
    }

সম্ভাব্য সমাধান

সুতরাং আপনি ভাবছেন, কেন আপনি ট্র্যাকে এটি রিপোর্ট করেন নি ? আমি ইতিমধ্যে আছে । আমার আশ্চর্যের বিষয় হল, 5 বছর আগে একই সমস্যাটির রূপরেখা তৈরি করে একটি আলাদা টিকিট তৈরি করা হয়েছিল।

আসুন এটির মুখোমুখি হয়ে, দেড় দশক কেটে গেছে। ইন্টারনেট বছরগুলিতে, এটি 30 টির মতো। সমস্যাটি পরিষ্কারভাবে ছেড়ে দেওয়া হয়েছে এবং মূলত কখনই স্থির করা হবে না (... যদি না আমরা এখানে সমাধান না করি)।

আমি এখানে একটি দুর্দান্ত থ্রেড পেয়েছি যেখানে একটি সমাধান প্রস্তাব দেওয়া হচ্ছে, তবে তার সমাধানটি কাজ করার সময় এটি কাস্টম $headersসেট নেই এমন ইমেলগুলি ভেঙে দেয় ।

আমরা এখানে প্রতিবার ক্রাশ। হয় মাল্টিপার্ট সংস্করণ সূক্ষ্মভাবে কাজ করে, এবং সাধারণ আনসেট $headersবার্তাগুলি না করে বা শ্লোকটি দেয়।

আমরা যে সমাধানটি নিয়ে এসেছি তা হ'ল:

if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) ) {
    $phpmailer->ContentType = $content_type . "; boundary=" . $boundary;
}
else {

        $content_type = apply_filters( 'wp_mail_content_type', $content_type );

    $phpmailer->ContentType = $content_type;

    // Set whether it's plaintext, depending on $content_type
    if ( 'text/html' == $content_type )
        $phpmailer->IsHTML( true );

    // If we don't have a charset from the input headers
    if ( !isset( $charset ) )
        $charset = get_bloginfo( 'charset' );
}

// Set the content-type and charset

/**
 * Filter the default wp_mail() charset.
 *
 * @since 2.3.0
 *
 * @param string $charset Default email charset.
 */
$phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset );

// Set custom headers
if ( !empty( $headers ) ) {
    foreach( (array) $headers as $name => $content ) {
        $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) );
    }

}

হ্যাঁ, আমি জানি, মূল ফাইলগুলি সম্পাদনা করা নিষিদ্ধ, আবার বসুন ... এটি মরিয়া ফিক্স এবং মূলটির জন্য কোনও স্থির সরবরাহের একটি দুর্বল প্রচেষ্টা ছিল।

আমাদের ফিক্সের সমস্যাটি হ'ল নতুন রেজিস্ট্রেশন, মন্তব্য, পাসওয়ার্ড রিসেট ইত্যাদির মতো ডিফল্ট ইমেলগুলি ফাঁকা বার্তা হিসাবে সরবরাহ করা হবে। সুতরাং আমাদের কাছে একটি ওয়ার্কিং wp_mail () স্ক্রিপ্ট রয়েছে যা মাল্টিপার্ট বার্তা প্রেরণ করবে তবে কিছুই নয় else

কি করো

মূল উদ্দেশ্যটি হ'ল মূল wp_mail () ফাংশন (কোনও কাস্টম সেন্ডমেল ফাংশন নয় ) ব্যবহার করে উভয় সাধারণ (প্লেইন পাঠ্য) এবং মাল্টিপার্ট বার্তাগুলি প্রেরণের একটি উপায় অনুসন্ধান করা ।

এটি সমাধান করার চেষ্টা করার সময়, আপনি যে মুখ্য সমস্যাটির মুখোমুখি হবেন তা হ'ল আপনি ডামি বার্তা প্রেরণে যে পরিমাণ সময় ব্যয় করেছেন তা পরীক্ষা করে এবং মূলত অ্যাসপিরিনের একটি বাক্স খোলার এবং মাইক্রোসফ্টে অভিশাপ দেওয়ার কারণ আপনি তাদের অভ্যস্ত দুর্ভাগ্যক্রমে ওয়ার্ডপ্রেস থাকাকালীন IE সমস্যাগুলি।

হালনাগাদ

@ ব্রোঞ্জার পোস্ট করা সমাধানটি $messageকন্টেন্ট-টাইপ কীড বিকল্পযুক্ত অ্যারে হতে দেয় । আমি নিশ্চিত করেছি যে এটি সমস্ত পরিস্থিতিতে কাজ করে।

সমস্যা সম্পর্কে সচেতনতা বাড়াতে অনুগ্রহ না হওয়া পর্যন্ত আমরা এই প্রশ্নটি উন্মুক্ত থাকতে দেব, সম্ভবত এটি এমন একটি স্তরে যেখানে এটি মূল স্থির করা হবে। $messageএকটি স্ট্রিং হতে পারে এমন বিকল্প সমাধান পোস্ট করতে নির্দ্বিধায় ।


1
হিসাবে wp_mail()ফাংশন প্লাগেবল আপনি (এবং অন্য সবাই, ব্যর্থ কোর ফিক্স) একজন ভাল সমাধান একটি আবশ্যক ব্যবহারযোগ্য প্লাগইন হিসাবে আপনার প্রতিস্থাপন সংজ্ঞা না হয় (WP- বিষয়বস্তু / মিউ-প্লাগ মধ্যে) না? কোন ক্ষেত্রে সেটিংয়ের পরে $phpmailer->ContentType = $content_type;মাল্টপার্ট / বাউন্ডারি চেকটি সরানো হবে না (এলসিংয়ের চেয়ে) কাজ করবে না?
বোনার

@ ব্রোঞ্জার আপনি কি দয়া করে আপনার সমাধানের বিস্তারিত বিবরণ লিখতে পারেন?
ক্রিস্টিন কুপার

1
ইয়ো, সম্পাদনা কোর প্রয়োজন হবে না কারণ wp_mailহয় প্লাগেবল । প্লাগিনে আসল ফাংশনটি অনুলিপি করুন, আপনার প্রয়োজন মতো এটি সম্পাদনা করুন এবং প্লাগইনটি সক্রিয় করুন। ওয়ার্ডপ্রেস মূল সম্পাদনা করার কোনও প্রয়োজন ছাড়াই মূল সম্পাদনের পরিবর্তে আপনার সম্পাদিত ফাংশনটি ব্যবহার করবে।
গাজাজ্যাপ

@ ক্রিসটাইনকুপার যেমনটি আপনি বলছেন টেস্টটি এমন রাজকীয় ব্যথা হওয়ায় আমি এটি করতে দ্বিধা বোধ করছি তবে @ rmccue / @ ম্যাটিরোব দ্বারা ট্র্যাকে প্রস্তাবিত প্যাচ কোর.ট্রাক.ওয়ার্ডপ্রেস.আর. / স্পিট / ১৫৪৪৮ দেখে মনে হচ্ছে এটি দেখতে খুব সুন্দর উপায় বলে মনে হচ্ছে যাও তাই আমি এর ভিত্তিতে একটি
অনিরীক্ষিত

2
@ ক্রিসটাইনকুপার যদি আপনি phpmailer এ সরল হন এবং টেক্সট বডিটি $ phpmailer-> AltBody তে সেট করেন তবে একই ত্রুটি ঘটে?
chifliiiii

উত্তর:


15

নিম্নলিখিত সংস্করণটি wp_mail()হল টিকিট https://core.trac.wordpress.org/ticket/15448 এ @ rmccue / @ MattyRob এর প্রয়োগ প্যাচ সহ , যা 4.2.2 এর জন্য রিফ্রেশ, যা $messageসামগ্রী-ধরণের সমন্বিত অ্যারে হতে দেয় কীড বিকল্প:

/**
 * Send mail, similar to PHP's mail
 *
 * A true return value does not automatically mean that the user received the
 * email successfully. It just only means that the method used was able to
 * process the request without any errors.
 *
 * Using the two 'wp_mail_from' and 'wp_mail_from_name' hooks allow from
 * creating a from address like 'Name <email@address.com>' when both are set. If
 * just 'wp_mail_from' is set, then just the email address will be used with no
 * name.
 *
 * The default content type is 'text/plain' which does not allow using HTML.
 * However, you can set the content type of the email by using the
 * 'wp_mail_content_type' filter.
 *
 * If $message is an array, the key of each is used to add as an attachment
 * with the value used as the body. The 'text/plain' element is used as the
 * text version of the body, with the 'text/html' element used as the HTML
 * version of the body. All other types are added as attachments.
 *
 * The default charset is based on the charset used on the blog. The charset can
 * be set using the 'wp_mail_charset' filter.
 *
 * @since 1.2.1
 *
 * @uses PHPMailer
 *
 * @param string|array $to Array or comma-separated list of email addresses to send message.
 * @param string $subject Email subject
 * @param string|array $message Message contents
 * @param string|array $headers Optional. Additional headers.
 * @param string|array $attachments Optional. Files to attach.
 * @return bool Whether the email contents were sent successfully.
 */
function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {
    // Compact the input, apply the filters, and extract them back out

    /**
     * Filter the wp_mail() arguments.
     *
     * @since 2.2.0
     *
     * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
     *                    subject, message, headers, and attachments values.
     */
    $atts = apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) );

    if ( isset( $atts['to'] ) ) {
        $to = $atts['to'];
    }

    if ( isset( $atts['subject'] ) ) {
        $subject = $atts['subject'];
    }

    if ( isset( $atts['message'] ) ) {
        $message = $atts['message'];
    }

    if ( isset( $atts['headers'] ) ) {
        $headers = $atts['headers'];
    }

    if ( isset( $atts['attachments'] ) ) {
        $attachments = $atts['attachments'];
    }

    if ( ! is_array( $attachments ) ) {
        $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) );
    }
    global $phpmailer;

    // (Re)create it, if it's gone missing
    if ( ! ( $phpmailer instanceof PHPMailer ) ) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer( true );
    }

    // Headers
    if ( empty( $headers ) ) {
        $headers = array();
    } else {
        if ( !is_array( $headers ) ) {
            // Explode the headers out, so this function can take both
            // string headers and an array of headers.
            $tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) );
        } else {
            $tempheaders = $headers;
        }
        $headers = array();
        $cc = array();
        $bcc = array();

        // If it's actually got contents
        if ( !empty( $tempheaders ) ) {
            // Iterate through the raw headers
            foreach ( (array) $tempheaders as $header ) {
                if ( strpos($header, ':') === false ) {
                    if ( false !== stripos( $header, 'boundary=' ) ) {
                        $parts = preg_split('/boundary=/i', trim( $header ) );
                        $boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) );
                    }
                    continue;
                }
                // Explode them out
                list( $name, $content ) = explode( ':', trim( $header ), 2 );

                // Cleanup crew
                $name    = trim( $name    );
                $content = trim( $content );

                switch ( strtolower( $name ) ) {
                    // Mainly for legacy -- process a From: header if it's there
                    case 'from':
                        $bracket_pos = strpos( $content, '<' );
                        if ( $bracket_pos !== false ) {
                            // Text before the bracketed email is the "From" name.
                            if ( $bracket_pos > 0 ) {
                                $from_name = substr( $content, 0, $bracket_pos - 1 );
                                $from_name = str_replace( '"', '', $from_name );
                                $from_name = trim( $from_name );
                            }

                            $from_email = substr( $content, $bracket_pos + 1 );
                            $from_email = str_replace( '>', '', $from_email );
                            $from_email = trim( $from_email );

                        // Avoid setting an empty $from_email.
                        } elseif ( '' !== trim( $content ) ) {
                            $from_email = trim( $content );
                        }
                        break;
                    case 'content-type':
                        if ( is_array($message) ) {
                            // Multipart email, ignore the content-type header
                            break;
                        }
                        if ( strpos( $content, ';' ) !== false ) {
                            list( $type, $charset_content ) = explode( ';', $content );
                            $content_type = trim( $type );
                            if ( false !== stripos( $charset_content, 'charset=' ) ) {
                                $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset_content ) );
                            } elseif ( false !== stripos( $charset_content, 'boundary=' ) ) {
                                $boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset_content ) );
                                $charset = '';
                            }

                        // Avoid setting an empty $content_type.
                        } elseif ( '' !== trim( $content ) ) {
                            $content_type = trim( $content );
                        }
                        break;
                    case 'cc':
                        $cc = array_merge( (array) $cc, explode( ',', $content ) );
                        break;
                    case 'bcc':
                        $bcc = array_merge( (array) $bcc, explode( ',', $content ) );
                        break;
                    default:
                        // Add it to our grand headers array
                        $headers[trim( $name )] = trim( $content );
                        break;
                }
            }
        }
    }

    // Empty out the values that may be set
    $phpmailer->ClearAllRecipients();
    $phpmailer->ClearAttachments();
    $phpmailer->ClearCustomHeaders();
    $phpmailer->ClearReplyTos();

    $phpmailer->Body= '';
    $phpmailer->AltBody= '';

    // From email and name
    // If we don't have a name from the input headers
    if ( !isset( $from_name ) )
        $from_name = 'WordPress';

    /* If we don't have an email from the input headers default to wordpress@$sitename
     * Some hosts will block outgoing mail from this address if it doesn't exist but
     * there's no easy alternative. Defaulting to admin_email might appear to be another
     * option but some hosts may refuse to relay mail from an unknown domain. See
     * https://core.trac.wordpress.org/ticket/5007.
     */

    if ( !isset( $from_email ) ) {
        // Get the site domain and get rid of www.
        $sitename = strtolower( $_SERVER['SERVER_NAME'] );
        if ( substr( $sitename, 0, 4 ) == 'www.' ) {
            $sitename = substr( $sitename, 4 );
        }

        $from_email = 'wordpress@' . $sitename;
    }

    /**
     * Filter the email address to send from.
     *
     * @since 2.2.0
     *
     * @param string $from_email Email address to send from.
     */
    $phpmailer->From = apply_filters( 'wp_mail_from', $from_email );

    /**
     * Filter the name to associate with the "from" email address.
     *
     * @since 2.3.0
     *
     * @param string $from_name Name associated with the "from" email address.
     */
    $phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name );

    // Set destination addresses
    if ( !is_array( $to ) )
        $to = explode( ',', $to );

    foreach ( (array) $to as $recipient ) {
        try {
            // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>"
            $recipient_name = '';
            if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) {
                if ( count( $matches ) == 3 ) {
                    $recipient_name = $matches[1];
                    $recipient = $matches[2];
                }
            }
            $phpmailer->AddAddress( $recipient, $recipient_name);
        } catch ( phpmailerException $e ) {
            continue;
        }
    }

    // If we don't have a charset from the input headers
    if ( !isset( $charset ) )
        $charset = get_bloginfo( 'charset' );

    // Set the content-type and charset

    /**
     * Filter the default wp_mail() charset.
     *
     * @since 2.3.0
     *
     * @param string $charset Default email charset.
     */
    $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset );

    // Set mail's subject and body
    $phpmailer->Subject = $subject;

    if ( is_string($message) ) {
        $phpmailer->Body = $message;

        // Set Content-Type and charset
        // If we don't have a content-type from the input headers
        if ( !isset( $content_type ) )
            $content_type = 'text/plain';

        /**
         * Filter the wp_mail() content type.
         *
         * @since 2.3.0
         *
         * @param string $content_type Default wp_mail() content type.
         */
        $content_type = apply_filters( 'wp_mail_content_type', $content_type );

        $phpmailer->ContentType = $content_type;

        // Set whether it's plaintext, depending on $content_type
        if ( 'text/html' == $content_type )
            $phpmailer->IsHTML( true );

        // For backwards compatibility, new multipart emails should use
        // the array style $message. This never really worked well anyway
        if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) )
            $phpmailer->AddCustomHeader( sprintf( "Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) );
    }
    elseif ( is_array($message) ) {
        foreach ($message as $type => $bodies) {
            foreach ((array) $bodies as $body) {
                if ($type === 'text/html') {
                    $phpmailer->Body = $body;
                }
                elseif ($type === 'text/plain') {
                    $phpmailer->AltBody = $body;
                }
                else {
                    $phpmailer->AddAttachment($body, '', 'base64', $type);
                }
            }
        }
    }

    // Add any CC and BCC recipients
    if ( !empty( $cc ) ) {
        foreach ( (array) $cc as $recipient ) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>"
                $recipient_name = '';
                if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) {
                    if ( count( $matches ) == 3 ) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddCc( $recipient, $recipient_name );
            } catch ( phpmailerException $e ) {
                continue;
            }
        }
    }

    if ( !empty( $bcc ) ) {
        foreach ( (array) $bcc as $recipient) {
            try {
                // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>"
                $recipient_name = '';
                if( preg_match( '/(.*)<(.+)>/', $recipient, $matches ) ) {
                    if ( count( $matches ) == 3 ) {
                        $recipient_name = $matches[1];
                        $recipient = $matches[2];
                    }
                }
                $phpmailer->AddBcc( $recipient, $recipient_name );
            } catch ( phpmailerException $e ) {
                continue;
            }
        }
    }

    // Set to use PHP's mail()
    $phpmailer->IsMail();

    // Set custom headers
    if ( !empty( $headers ) ) {
        foreach ( (array) $headers as $name => $content ) {
            $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) );
        }
    }

    if ( !empty( $attachments ) ) {
        foreach ( $attachments as $attachment ) {
            try {
                $phpmailer->AddAttachment($attachment);
            } catch ( phpmailerException $e ) {
                continue;
            }
        }
    }

    /**
     * Fires after PHPMailer is initialized.
     *
     * @since 2.2.0
     *
     * @param PHPMailer &$phpmailer The PHPMailer instance, passed by reference.
     */
    do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );

    // Send!
    try {
        return $phpmailer->Send();
    } catch ( phpmailerException $e ) {
        return false;
    }
}

সুতরাং আপনি যদি এটি আপনার উদাহরণস্বরূপ "ডাব্লুপি-কনটেন্ট / মিউ-প্লাগিনস / ফাংশন.ফপি" ফাইলটিতে রাখেন তবে তা ডাব্লুপি সংস্করণকে ওভাররাইড করবে। শিরোনামগুলির সাথে কোনও গোলমাল ছাড়াই এটির দুর্দান্ত ব্যবহার রয়েছে, যেমন:

// Set $to to an hotmail.com or outlook.com email
$to = "YourEmail@hotmail.com";

$subject = 'wp_mail testing multipart';

$message['text/plain'] = 'Hello world! This is plain text...';
$message['text/html'] = '<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>

<p>Hello World! This is HTML...</p> 

</body>
</html>';

add_filter( 'wp_mail_from', $from_func = function ( $from_email ) { return 'foo@bar.com'; } );
add_filter( 'wp_mail_from_name', $from_name_func = function ( $from_name ) { return 'Foo'; } );

// send email
wp_mail( $to, $subject, $message );

remove_filter( 'wp_mail_from', $from_func );
remove_filter( 'wp_mail_from_name', $from_name_func );

দয়া করে মনে রাখবেন আমি এটি সত্যিকারের ইমেলগুলির সাথে পরীক্ষা করি নি ...


আমি অবশ্যই এটি প্লাগইন যুক্ত করতে এবং পরীক্ষার কোডটি চালিয়েছি; এটা কাজ করেছে. আমি ডিফল্ট মূল বিজ্ঞপ্তিগুলি (নতুন ব্যবহারকারী বিজ্ঞপ্তি ইত্যাদি) পরীক্ষা করেছি এবং এটি খুব কার্যকর হয়েছে। আমি এই সপ্তাহান্তে পরীক্ষা চালিয়ে যাব এবং প্লাগইনগুলি এটির সাথে কীভাবে কাজ করবে তা এবং মূলত যদি সমস্ত কিছু কাজ করে তবে দেখুন। আমি বিশেষভাবে বার্তাটির কাঁচা ডেটা দেখব। এটি খুব সময় সাশ্রয়ী মূল্যের কাজ হবে তবে নিশ্চিত আশ্বাস, কাজ শেষ হয়ে গেলে আমি প্রতিবেদন করব। যদি এমন কোনও পরিস্থিতি দেখা যায় যেখানে ডাব্লুপি_মেল () কাজ করবে না (যখন তা অন্যথায় হওয়া উচিত), দয়া করে আমাকে জানান। এই উত্তরের জন্য আপনাকে ধন্যবাদ।
খ্রীস্টিন কুপার

ভাল স্টাফ, আমি আউটপুটটিকে চোখের ছাঁটাই করে দেখছি এবং এটি দেখতে ভাল লাগছে - আসলে প্যাচটি কেবল অ্যারে পাস করার ক্ষেত্রে ডাব্লুপিমেইল পিএইচপিমেইলারের স্ট্যান্ডার্ড রক সলিড প্রসেসিং ব্যবহার করে এবং অন্যথায় ডজ ডাব্লুপি স্টাফের (পূর্ববর্তী সামঞ্জস্যের জন্য) ডিফল্ট হয় সুতরাং এটি ভাল হওয়া উচিত (স্পষ্টতই কুডোগুলি প্যাচ লেখকদের কাছে যায়) ... আমি এখন থেকে এটি ব্যবহার করতে যাচ্ছি (এবং শেষ পর্যন্ত বিপরীতমুখী ফিটিং) - এবং এইচটিএমএল / প্লেইন উভয়ই ব্যবহার করে তথ্য পুনরায় ধন্যবাদ জানাতে ধন্যবাদ স্প্যাম হিসাবে চিহ্নিত হওয়ার সম্ভাবনা হ্রাস করুন ...
বনগার

1
আমরা এটি সম্ভাব্য সমস্ত পরিস্থিতিতে পরীক্ষা করেছি এবং এটি দুর্দান্ত কাজ করছে। আমরা আগামীকাল একটি নিউজলেটার প্রকাশ করব এবং আমরা দেখতে পাব যে আমরা ব্যবহারকারীদের কাছ থেকে কোনও অভিযোগ পেয়েছি কিনা। কেবলমাত্র ছোটখাটো পরিবর্তনগুলি যা দরকার তা হ'ল ডিবিতে প্রবেশের সময় অ্যারেটি স্যানিটাইজ / আনসানাইটিজ করা (ডিবিতে একটি ক্রুতে বার্তা রয়েছে যেখানে একটি ক্রোন এটি ছোট বাল্কে প্রেরণ করে)। অনুগ্রহ না হওয়া পর্যন্ত আমি এই প্রশ্নটি খোলা এবং মুলতুবি থাকার অনুমতি দেব যাতে আমরা এই বিষয়ে সচেতনতা আনতে পারি। আশা করা যায়, এই প্যাচ, বা একটি বিকল্প মূল যোগ করা হবে। বা আরও গুরুত্বপূর্ণ, কেন না। এরা কী ভাবছে!
ক্রিস্টিন কুপার

আমি এলোমেলোভাবে লক্ষ্য করেছি যে আপনি লিঙ্কযুক্ত ট্র্যাকের টিকিটে আপডেট করেছেন performed এটি কি এই কোডটির আপডেট? যদি তা হয় তবে দয়া করে আপনার উত্তরটি এখানে সম্পাদনা করেও দয়া করে এই আপডেটটি পোস্ট করতে পারেন যাতে এই উত্তরটি আপটোডেট থাকে? আপনাকে অনেক ধন্যবাদ.
খ্রীস্টিন কুপার

হাই, না এটি কেবল বর্তমান ট্রাঙ্কের বিরুদ্ধে প্যাচকে রিফ্রেশ করেছিল যাতে এটি কোনও দ্বন্দ্ব ছাড়াই মার্জ হয়ে যায় (এটি কিছুটা মনোযোগ পাওয়ার আশায়), কোডটি হুবহু একই ...
4

4

এটি আসলেই কোনও ওয়ার্ডপ্রেস বাগ নয়, এটি phpmailerকাস্টম শিরোনামকে মঞ্জুরি দেয় না এমন একটি ... যদি আপনি দেখুন class-phpmailer.php:

public function getMailMIME()
{
    $result = '';
    $ismultipart = true;
    switch ($this->message_type) {
        case 'inline':
            $result .= $this->headerLine('Content-Type', 'multipart/related;');
            $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
            break;
        case 'attach':
        case 'inline_attach':
        case 'alt_attach':
        case 'alt_inline_attach':
            $result .= $this->headerLine('Content-Type', 'multipart/mixed;');
            $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
            break;
        case 'alt':
        case 'alt_inline':
            $result .= $this->headerLine('Content-Type', 'multipart/alternative;');
            $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
            break;
        default:
            // Catches case 'plain': and case '':
            $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
            $ismultipart = false;
            break;
    }

আপনি আপত্তিজনক ডিফল্ট কেসটি চরসেট এবং কোনও সীমানা দিয়ে অতিরিক্ত শিরোনাম লাইন আউটপুট দিচ্ছেন তা দেখতে পাচ্ছেন। ফিল্টার দ্বারা সামগ্রী প্রকার সেট করা কেবল এটি নিজেই সমাধান করে না কারণ altএখানে message_typeকেসটি পরীক্ষা করে সেট করা AltBodyহয়েছে এটি সামগ্রীর ধরণের চেয়ে খালি নয়।

protected function setMessageType()
{
    $type = array();
    if ($this->alternativeExists()) {
        $type[] = 'alt';
    }
    if ($this->inlineImageExists()) {
        $type[] = 'inline';
    }
    if ($this->attachmentExists()) {
        $type[] = 'attach';
    }
    $this->message_type = implode('_', $type);
    if ($this->message_type == '') {
        $this->message_type = 'plain';
    }
}

public function alternativeExists()
{
    return !empty($this->AltBody);
}

শেষ পর্যন্ত এর অর্থ কী হবে আপনি যখনই কোনও ফাইল বা ইনলাইন চিত্র সংযুক্ত করেন বা সেট করেন AltBody, আপত্তিজনক বাগটি বাইপাস করা উচিত। এটিও মানে কারণ যত তাড়াতাড়ি আছে একটি বিষয়বস্তুর প্রকার স্পষ্টভাবে সেট করতে কোন প্রয়োজন নেই AltBodyএটা সেট করা হয় multipart/alternativeদ্বারা phpmailer

সুতরাং সহজ উত্তরটি হ'ল:

add_action('phpmailer_init','wp_mail_set_text_body');
function wp_mail_set_text_body($phpmailer) {
     if (empty($phpmailer->AltBody)) {$phpmailer->AltBody = strip_tags($phpmailer->Body);}
}

তারপরে আপনার স্পষ্টভাবে শিরোনামগুলি সেট করার দরকার নেই, আপনি সহজভাবে এটি করতে পারেন:

 $message ='<html>
 <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 </head>
 <body>
     <p>Hello World! This is HTML...</p> 
 </body>
 </html>';

 wp_mail($to,$subject,$message);

দুর্ভাগ্যক্রমে phpmailerক্লাসে অনেকগুলি ফাংশন এবং বৈশিষ্ট্য সুরক্ষিত থাকে, যদি না হয় তবে বৈধ বিকল্প হ'ল প্রেরণের আগে হুকের MIMEHeadersমাধ্যমে সম্পত্তিটি চেক করা এবং ওভাররাইড করা হবে phpmailer_init


2

আমি একটি প্লাগইন প্রকাশ করেছি যাতে ব্যবহারকারীরা ওয়ার্ডপ্রেসে এইচটিএমএল টেমপ্লেট ব্যবহার করতে পারেন এবং আমি এখনই একটি সাধারণ পাঠ্য ফ্যালব্যাক যোগ করতে দেব সংস্করণে খেলছি । আমি নিম্নলিখিতগুলি করেছি এবং আমার পরীক্ষাগুলিতে আমি কেবলমাত্র একটি সীমানা যুক্ত দেখতে পেয়েছি এবং ইমেলগুলি হটমেলকে জরিমানা করছে।

add_action( 'phpmailer_init', array($this->mailer, 'send_email' ) );

/**
* Modify php mailer body with final email
*
* @since 1.0.0
* @param object $phpmailer
*/
function send_email( $phpmailer ) {

    $message            =  $this->add_template( apply_filters( 'mailtpl/email_content', $phpmailer->Body ) );
    $phpmailer->AltBody =  $this->replace_placeholders( strip_tags($phpmailer->Body) );
    $phpmailer->Body    =  $this->replace_placeholders( $message );
}

সুতরাং মূলত আমি এখানে যা করছি তা হল phpmailer অবজেক্টটি সংশোধন করা, এইচটিএমএল টেমপ্লেটের অভ্যন্তরে বার্তাটি লোড করুন এবং এটি শারীরিক সম্পত্তিতে সেট করুন। এছাড়াও আমি আসল বার্তাটি নিয়েছি এবং আল্টবডি সম্পত্তি সেট করেছি।


2

আমার সহজ সমাধানটি এইভাবে html2text https://github.com/soundasleep/html2text ব্যবহার করা :

add_action( 'phpmailer_init', 'phpmailer_init' );

//http://wordpress.stackexchange.com/a/191974
//http://stackoverflow.com/a/2564472
function phpmailer_init( $phpmailer )
{
  if( $phpmailer->ContentType == 'text/html' ) {
    $phpmailer->AltBody = Html2Text\Html2Text::convert( $phpmailer->Body );
  }
}

এখানে https://gist.github.com/ewake/6c4d22cd856456480bd77b988b5c9e80 এছাড়াও সম্পর্কে একটি গিস্ট।


2

যে কেউ 'phpmailer_init' হুক ব্যবহার করছেন তাদের নিজস্ব 'AltBody' যুক্ত করার জন্য:

বিকল্প টেক্সট বডিটি বিভিন্ন ধরণের মেলগুলি প্রেরণের জন্য পুনরায় ব্যবহার করা হয়, যদি না আপনি এটি ম্যানুয়ালি সাফ করেন! ওয়ার্ডপ্রেস এটি wp_mail () এ সাফ করে না কারণ এটি এই সম্পত্তিটি ব্যবহারের আশা করে না।

ফলস্বরূপ প্রাপকরা তাদের জন্য নয় এমন মেলগুলি সম্ভাব্যরূপে গ্রহণ করবে। ভাগ্যক্রমে HTML- সক্ষম মেল ক্লায়েন্ট ব্যবহারকারী বেশিরভাগ লোকেরা পাঠ্য সংস্করণটি দেখতে পাবেন না, তবে এটি এখনও মূলত একটি সুরক্ষা সমস্যা।

ভাগ্যক্রমে একটি সহজ ফিক্স আছে। এটিতে ওল্ডডি প্রতিস্থাপন বিট অন্তর্ভুক্ত; মনে রাখবেন যে আপনার এইচটিএমএল 2 পাঠ্য পিএইচপি লাইব্রেরি দরকার:

add_filter( 'wp_mail', 'wpse191923_force_phpmailer_reinit_for_multiple_mails', -1 );
function wpse191923_force_phpmailer_reinit_for_multiple_mails( $wp_mail_atts ) {
  global $phpmailer;

  if ( $phpmailer instanceof PHPMailer && $phpmailer->alternativeExists() ) {
    // AltBody property is set, so WordPress must already have used this
    // $phpmailer object just now to send mail, so let's
    // clear the AltBody property
    $phpmailer->AltBody = '';
  }

  // Return untouched atts
  return $wp_mail_atts;
}

add_action( 'phpmailer_init', 'wpse191923_phpmailer_init_altbody', 1000, 1 );
function wpse191923_phpmailer_init_altbody( $phpmailer ) {
  if ( ( $phpmailer->ContentType == 'text/html' ) && empty( $phpmailer->AltBody ) ) {
    if ( ! class_exists( 'Html2Text\Html2Text' ) ) {
      require_once( 'Html2Text.php' );
    }
    if ( ! class_exists( 'Html2Text\Html2TextException' ) ) {
      require_once( 'Html2TextException.php' );
    }
    $phpmailer->AltBody = Html2Text\Html2Text::convert( $phpmailer->Body );
  }
}

এই সমস্যাটি সমাধানের জন্য আমি একটি ডাব্লুপি প্লাগইনটির সংক্ষিপ্তসারও এখানে করেছি: https://gist.github.com/youri--/c4618740b7c50c549314eaebc9f78661

দুর্ভাগ্যক্রমে আমি পূর্বের বর্ণিত হুক ব্যবহার করে অন্যান্য সমাধানগুলি সম্পর্কে এ সম্পর্কে তাদের সতর্ক করতে মন্তব্য করতে পারি না, কারণ আমার কাছে মন্তব্য করার মতো পর্যাপ্ত প্রতিনিধি নেই don't


1

এটি এখানে প্রাথমিক পোস্টের সঠিক উত্তর নাও হতে পারে, তবে এটি কোনও এলডি বডি স্থাপনের বিষয়ে সরবরাহিত কিছু সমাধানের বিকল্প

মূলত, আমাকে কিছু রূপান্তর / স্ট্রিপ্যাগ এবং হোয়াট নোটের উপর নির্ভর না করে এইচটিএমএল অংশে অতিরিক্ত স্বতন্ত্র ব্যক্তি (অর্থাত্ প্লেইন টেক্সট) সেট করা দরকার ছিল। সুতরাং আমি এটি নিয়ে এসেছি যা মনে হয় ঠিক কাজ করে

/* setting the message parts for wp_mail()*/
$markup = array();
$markup['html'] = '<html>some html</html>';
$markup['plaintext'] = 'some plaintext';
/* message we are sending */    
$message = maybe_serialize($markup);


/* setting alt body distinctly */
add_action('phpmailer_init', array($this, 'set_alt_mail_body'));

function set_alt_mail_body($phpmailer){
    if( $phpmailer->ContentType == 'text/html' ) {
        $body_parts = maybe_unserialize($phpmailer->Body);

        if(!empty($body_parts['html'])){
            $phpmailer->MsgHTML($body_parts['html']);
        }

        if(!empty($body_parts['plaintext'])){
            $phpmailer->AltBody = $body_parts['plaintext'];
        }
    }   
}

0

আপনি যদি ওয়ার্ডপ্রেস কোরটিতে কোনও কোড দ্বন্দ্ব তৈরি করতে না চান তবে আমি মনে করি বিকল্প বা সহজ সমাধান হ'ল phpmailer_initপ্রকৃত মেইল ​​প্রেরণের আগে এটির সাথে কাজ করা wp_mail। আমার ব্যাখ্যাটি সরল করতে নীচের কোডের উদাহরণটি দেখুন:

<?php 

$to = '';
$subject = '';
$from = '';
$body = 'The text html content, <html>...';

$headers = "FROM: {$from}";

add_action( 'phpmailer_init', function ( $phpmailer ) {
    $phpmailer->AltBody = 'The text plain content of your original text html content.';
} );

wp_mail($to, $subject, $body, $headers);

আপনি যদি পিএইচপিএমেলার শ্রেণীর AltBodyসম্পত্তিতে কোনও সামগ্রী যুক্ত করেন তবে ডিফল্ট সামগ্রী প্রকারটি স্বয়ংক্রিয়ভাবে সেট হয়ে যাবে multipart/alternative

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.