Content-Type: multipart/alternative in Wordpress with wp_mail() - wordpress

Is it is possible to send emails with the wp_mail() function having its Content-Type: multipart/alternative ?
I need to send emails that can be shown as HTML or Plain Text depending on what medium interprets the email.
Any suggestions are welcome!

It's right there in the wp_mail() documentation (under Usage):
The default content type is 'text/plain' which does not allow using HTML. You can set the content type of the email either by using the 'wp_mail_content_type' filter (see example below), or by including a header like "Content-type: text/html". Be careful to reset 'wp_mail_content_type' back to 'text/plain' after you send your message, though, because failing to do so could lead to unexpected problems with e-mails from WP or plugins/themes.
(emphasis mine)
The 2nd example on the page shows you how to do it (the example uses text/html but you should be able to use your multipart/alternative instead.

It's totally possible when you have access to the phpmailer instance.
if ($is_html)
add_action('phpmailer_init', 'fix_mimeheader');
// more code.
wp_mail( $to, $subject, $html_message, $headers, $attachments );
// ...
function fix_mimeheader( $phpmailer ) {
// Generate $text_message here.
// ...
$phpmailer->AltBody = $text_message;
}
The message sent to wp_mail should be your html code. You also shouldn't include any content type headers. I currently use from, cc and reply-to in the plugin i've made.
If the email is being sent as HTML, I run the action which sets the AltBody property on the phpmailer object directly. This then causes the proper flags to convert the email to a multipart/alternative email.

You can use the wp_mail_content_type filter, which was now been documented in the Codex.
The wp_mail documentation about resetting the content type back to 'text/plain' is kind of misleading, IMO. Since this is a filter, you don't really "reset" it. What you need to consider in your filter is some conditional logic to determine when you need to use multipart vs. plain text or html:
add_filter( 'wp_mail_content_type', 'my_mail_content_type' );
function my_mail_content_type( $content_type ) {
if( $some_condition ) {
return 'multipart/mixed';
} else {
return 'text/plain';
}
}

Related

How to return binary data from custom wordpress rest api endpoint

I am writing a custom endpoint for a REST api in wordpress, following the guide here: https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/
I am able to write a endpoint that returns json data. But how can I write an endpoint that returns binary data (pdf, png, and similar)?
My restpoint function returns a WP_REST_Response (or WP_Error in case of error).
But I do not see what I should return if I want to responde with binary data.
Late to the party, but I feel the accepted answer does not really answer the question, and Google found this question when I searched for the same solution, so here is how I eventually solved the same problem (i.e. avoiding to use WP_REST_Response and killing the PHP script before WP tried to send anything else other than my binary data).
function download(WP_REST_Request $request) {
$dir = $request->get_param("dir");
// The following is for security, but my implementation is out
// of scope for this answer. You should either skip this line if
// you trust your client, or implement it the way you need it.
$dir = sanitize_path($dir);
$file = $request->get_param("file");
// See above...
$file = sanitize_path($file);
$sandbox = "/some/path/with/shared/files";
// full path to the file
$path = $sandbox.$dir.$file;
$name = basename($path);
// get the file mime type
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $path);
// tell the browser what it's about to receive
header("Content-Disposition: attachment; filename=$name;");
header("Content-Type: $mime_type");
header("Content-Description: File Transfer");
header("Content-Transfer-Encoding: binary");
header('Content-Length: ' . filesize($path));
header("Cache-Control: no-cache private");
// stream the file without loading it into RAM completely
$fp = fopen($path, 'rb');
fpassthru($fp);
// kill WP
exit;
}
I would look at something called DOMPDF. In short, it streams any HTML DOM straight to the browser.
We use it to generate live copies of invoices straight from the woo admin, generate brochures based on $wp_query results etc. Anything that can be rendered by a browser can be streamed via DOMPDF.

How to assign a SendGrid category with Contact Form 7 and WP Mail SMTP

I'm trying to assign a SendGrid category on the emails sent by a form.
SendGrid documentation mentions the use of X-SMTPAPI, it says it should contain a json object in there, and adding {'category': 'cat1'} is supposed to do the trick.
This is what I've tried.
As WP Mail SMTP uses the v3 API to send mail, you need to add your custom categories to the request body.
You can do this with the following piece of code:
function wp_mail_smtp_add_cat( $body, $mailer ) {
$body['categories'] = array('testcat');
return $body;
}
add_filter( 'wp_mail_smtp_providers_mailer_get_body', 'wp_mail_smtp_add_cat', 10, 2 );
For other parameters, check the v3 documentation: https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/index.html

contact form 7 wordpress plugin not working properly

I am using contact form 7 wordpress plugin for one of website and facing problem to adding action after sending mail.
I want to call some CRM Api when data submitted by the user and also sent mail to admin so i have tried following way.
I added action and function to function.php
1)
add_action('init', create_function('',
'add_action("wpcf7_admin_after_mail", "leads_integration_wp_cf7");'));
function leads_integration_wp_cf7($cf7 ) {
$title = $contact_form->title;
$submission = WPCF7_Submission::get_instance();
if($submission)
{
$posted_data = $submission->get_posted_data();
//using curl make request here
}
}
So using this way i got mail but i am thinking my function(leads_integration_wp_cf7) did not called and i did not get entry in CRM.
2)
add_action('wpcf7_before_send_mail', 'leads_integration_wp_cf7');
using this way i made successfully request to CRM but mail sending stop.on a form page ajax preloader loading,loading, and not redirect on url.
Anybody face this issue i am new in wordpress.
The action wpcf7_admin_after_mail is called in edit-contact-form.php file and it is used for form control ui purpose so it will not be helpful for this case.
The action wpcf7_before_send_mail is correct for doing some task when contact form is posted and email is sent, can you confirm that mail is working properly if this action hook is not applied?
Also try renaming the param $cf7 to $contact_form
function leads_integration_wp_cf7($cf7) {
To
function leads_integration_wp_cf7($contact_form) {
{code: 'invalid_json', message: 'The response is not a valid JSON response.'}
code: "invalid_json"
message: "The response is not a valid JSON response."

wp_mail_from: different from address each time

I have a form. Where user gives their name and email address. The I use the custom plugin to send the mail. The requirement is I need to send the mail on behalf of the user who signed.
Now in wp_mail how to achieve that?
I know about this filter: wp_mail_from. But how to call it every time wp_mail is called and set different from address?
Finally I also want to clear the wp_mail_from filter so that it doesn't affect the other forms.
Thanks,
wp_mail accepts "headers"
http://codex.wordpress.org/Function_Reference/wp_mail#Using_.24headers_To_Set_.22From:.22.2C_.22Cc:.22_and_.22Bcc:.22_Parameters
<?php
$headers = 'From: My Name <myname#example.com>' . "\r\n";
wp_mail('test#example.org', 'subject', 'message', $headers );
?>

Loading Google Maps API with wp_enqueue_script

I'm trying to load the Google Maps API using the following syntax:
add_action('admin_enqueue_scripts', 'load_google_maps');
...
function load_google_maps()
{
// The actual API key is configured in an options page
$key = get_option('google_maps_api_key');
$gmaps_url = 'http://maps.googleapis.com/maps/api/js?key=' . $key . '&sensor=false';
wp_enqueue_script('google-maps', $gmaps_url, NULL, NULL);
}
WordPress is escaping the "&" to "&#038". This actually makes the Google server reject the request. When I type it directly into browser address bar with "&sensor=false" at the end, it loads fine.
I saw a bug of this kind mentioned in the WordPress trac system: http://core.trac.wordpress.org/ticket/9243 but it was dismissed as invalid, and the admin responding to the request showed somehow that the "&#038" approach was fine. It is definitely not fine from Google's point of view.
I could of course just get the function to echo the HTML as a script tag, but I'd rather use the wp_enqueue_script system if possible.
Anyone know of a solution to this?
Cheers,
raff
I've got something similar in our code, and it's working fine (even encoded as &#038). I suspect your problem is that it's being double-encoded, as you already have &. Trying changing it to:
$gmaps_url = 'http://maps.googleapis.com/maps/api/js?key=' . $key . '&sensor=false';
For what it's worth, our (working) code is:
wp_register_script('googlemaps', 'http://maps.googleapis.com/maps/api/js?' . $locale . '&key=' . GOOGLE_MAPS_V3_API_KEY . '&sensor=false', false, '3');
wp_enqueue_script('googlemaps');
($locale in this case is set to hl=en)
Edit
Looks like the behaviour's changed in the latest version of WordPress - the above doesn't work (but I'll leave it for people on legacy versions). The only alternative I can see to echoing the script is to add a clean_url filter, something like this:
add_filter('clean_url', 'so_handle_038', 99, 3);
function so_handle_038($url, $original_url, $_context) {
if (strstr($url, "googleapis.com") !== false) {
$url = str_replace("&", "&", $url); // or $url = $original_url
}
return $url;
}
Pretty ugly, but perhaps marginally better than echoing the script, as it'll still use the WordPress dependency management.

Resources