सारांश
WP कोर में एक बग, भेजने की वजह से बहुखण्डीय के साथ ईमेल (html / पाठ) wp_mail () (स्पैम फ़ोल्डर में समाप्त ईमेल की संभावना को कम करने के लिए) होगा विडंबना यह है कि के साथ अपने डोमेन हॉटमेल (और अन्य माइक्रोसॉफ्ट ईमेल) द्वारा अवरुद्ध किया जा रहा होता है।
यह एक जटिल समस्या है जिसका उद्देश्य मैं किसी को एक व्यावहारिक समाधान खोजने में मदद करने के प्रयास में बहुत विस्तार से तोड़ सकता हूं जिसे अंततः कोर में लागू किया जा सकता है।
यह एक पुरस्कृत पाठ है। शुरू करते हैं...
बग
स्पैम फ़ोल्डरों में आपके न्यूज़लेटर के ईमेल समाप्त होने से बचने के लिए सबसे आम सलाह मल्टीपार्ट संदेश भेजना है।
मल्टी-पार्ट (माइम) एक ईमेल में एक ई-मेल संदेश के एक HTML और पाठ भाग दोनों को भेजने के लिए संदर्भित करता है। जब कोई क्लाइंट मल्टीपार्ट संदेश प्राप्त करता है, तो वह HTML संस्करण को स्वीकार कर सकता है यदि वह HTML को रेंडर कर सकता है, अन्यथा यह सादे पाठ संस्करण को प्रस्तुत करता है।
यह काम करने के लिए सिद्ध है। जब हम जीमेल पर भेजते हैं, हमारे सभी ईमेल स्पैम फोल्डर में तब तक उतरते हैं, जब तक कि हम मुख्य इनबॉक्स के माध्यम से आने पर संदेशों को मल्टीपार्ट करने के लिए नहीं बदलते। उत्तम सामग्री।
अब, जब wp_mail () के माध्यम से मल्टीपार्ट संदेश भेजते हैं, तो यह दो बार (यदि कस्टम रूप से सेट किया गया है) और एक बार बिना कंटेंट टाइप (मल्टीपार्ट / *) के दो बार आउटपुट करता है। इस व्यवहार के परिणामस्वरूप ईमेल को एक कच्चे संदेश के रूप में प्रदर्शित किया जाता है और कुछ ईमेलों पर मल्टीपार्ट नहीं किया जाता है, जिसमें सभी Microsoft (हॉटमेल, आउटलुक, आदि) शामिल हैं ...
Microsoft इस संदेश को रद्दी के रूप में चिह्नित करेगा, और कुछ संदेश जो प्राप्त करेगा, उसे प्राप्तकर्ता द्वारा मैन्युअल रूप से फ़्लैग किया जाएगा। दुर्भाग्य से , Microsoft ईमेल पते व्यापक रूप से उपयोग किए जाते हैं। हमारे 40% ग्राहक इसका उपयोग करते हैं।
इसकी पुष्टि Microsoft द्वारा हाल ही में हमारे द्वारा की गई ईमेल एक्सचेंज के माध्यम से की गई।
संदेशों को चिह्नित करने से डोमेन पूरी तरह से अवरुद्ध हो जाएगा । इसका मतलब यह है कि संदेश स्पैम फ़ोल्डर में नहीं भेजे जाएंगे , वे प्राप्तकर्ता को बिल्कुल भी वितरित नहीं किए जाएंगे ।
हमने अपना मुख्य डोमेन अब तक 3 बार अवरुद्ध किया है।
क्योंकि यह WP कोर में एक बग है, मल्टीपार्ट संदेश भेजने वाले प्रत्येक डोमेन को अवरुद्ध किया जा रहा है। समस्या यह है कि अधिकांश वेबमास्टरों को पता नहीं है कि क्यों। मैंने अपने शोध करते समय और अन्य उपयोगकर्ताओं को मंचों पर इस पर चर्चा करते हुए इसकी पुष्टि की है। इसके लिए कच्चे कोड में देरी करने और इस प्रकार के ईमेल संदेशों को काम करने का एक अच्छा ज्ञान होना आवश्यक है, जिन्हें हम अगले करने जा रहे हैं ...
इसे कोड में तोड़ देते हैं
हॉटमेल / आउटलुक अकाउंट बनाएं। फिर, निम्न कोड चलाएँ:
// 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;
}
}
}
संभावित समाधान
तो आप सोच रहे होंगे, कि आपने trac पर यह रिपोर्ट क्यों नहीं की ? मेरे पास पहले से है । मेरे महान आश्चर्य के लिए, उसी समस्या को रेखांकित करते हुए 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 () स्क्रिप्ट है जो मल्टीपार्ट संदेश भेजेगा लेकिन कुछ और नहीं।
क्या करें
यहाँ उद्देश्य सामान्य wp_mail () फ़ंक्शन (कस्टम कस्टम मेलमेल फ़ंक्शन नहीं ) का उपयोग करके दोनों सामान्य (सादे पाठ) और मल्टीपार्ट संदेश भेजने का एक तरीका खोजना है ।
इसे हल करने का प्रयास करते समय, आपके सामने आने वाली मुख्य समस्या समय की मात्रा है जो आप डमी संदेश भेजने पर खर्च करेंगे, अगर वे प्राप्त करते हैं और मूल रूप से एस्पिरिन का एक बॉक्स खोल रहे हैं और Microsoft पर शाप दे रहे हैं क्योंकि आप उनके लिए उपयोग किए जाते हैं IE मुद्दों जबकि यहाँ gremlin दुर्भाग्य से वर्डप्रेस है।
अद्यतन करें
@Bonger द्वारा पोस्ट किया गया समाधान $message
सामग्री-प्रकार के वैकल्पिक विकल्पों से युक्त एक सरणी होने की अनुमति देता है। मैंने पुष्टि की है कि यह सभी परिदृश्यों में काम करता है।
हम इस सवाल को तब तक खुला रहने देंगे जब तक कि समस्या के बारे में जागरूकता बढ़ाने के लिए बाउंटी भाग न जाए, हो सकता है कि यह उस स्तर पर हो जहां इसे कोर में तय किया जाएगा। एक वैकल्पिक समाधान पोस्ट करने के लिए स्वतंत्र महसूस करें जहां $message
एक स्ट्रिंग हो सकती है।
wp_mail
यह प्लग करने योग्य है । मूल फ़ंक्शन को एक प्लगइन में कॉपी करें, इसे संपादित करें जैसे आपको ज़रूरत है और प्लगइन को सक्रिय करें। वर्डप्रेस मूल के बजाय आपके संपादित फ़ंक्शन का उपयोग करेगा, जिसमें कोर को संपादित करने की कोई आवश्यकता नहीं है।
wp_mail()
फ़ंक्शन प्लग करने योग्य है, आपके प्रतिस्थापन को एक-उपयोग प्लगइन (wp-content / mu-plugins में) के रूप में परिभाषित नहीं कर रहा है, आपके लिए एक अच्छा समाधान नहीं है (और बाकी सब, कोर फिक्सिंग विफल)? किस मामले में सेटिंग के बाद मल्टीपार्ट / बाउंड्री चेक को स्थानांतरित नहीं किया जाएगा$phpmailer->ContentType = $content_type;
(काम करने के बजाय) काम नहीं करेगा?