Ok, so this was a bit of a beast.
I've written a demo plugin with the following structure:
kia-ajax-email.php
- includes
-- class-wc-test-ajax-email.php
-- js
-- script.js
-- templates
-- emails
-- test.php
-- plain
-- test.php
The main plugin file kia-ajax-email.php
This file is responsible for enqueuing the script, adding your custom email class, creating a button on the single product page, and registering an action as one that triggers a WooCommerce email:
<?php
/**
* Plugin Name: Test Ajax Email
* Plugin URI: http://stackoverflow.com/q/35018177/383847
* Description: Demo plugin for sending email via ajax
* Author: helgatheviking
* Author URI: http://www.kathyisawesome.com
* Version: 0.1
*
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* get plugin path
*
* @since 0.1
*/
function kia_ajax_email_plugin_path(){
return untrailingslashit( plugin_dir_path( __FILE__ ) );
}
/**
* Add a custom email to the list of emails WooCommerce should load
*
* @since 0.1
* @param array $email_classes available email classes
* @return array filtered available email classes
*/
function kia_add_custom_email( $email_classes ) {
// include our custom email class
require_once( 'includes/class-wc-test-ajax-email.php' );
// add the email class to the list of email classes that WooCommerce loads
$email_classes['WC_Test_Ajax_Email'] = new WC_Test_Ajax_Email();
return $email_classes;
}
add_filter( 'woocommerce_email_classes', 'kia_add_custom_email' );
/**
* Enqueue the scripts with apprpriate vars
*
* @since 0.1
*/
function kia_ajax_email_js(){
wp_enqueue_script( 'kia_ajax_email', plugins_url( 'js/script.js', __FILE__ ), array('jquery'), '1.0.0', true );
wp_localize_script( 'kia_ajax_email', 'kia_ajax_email', array(
'ajax_url' => WC()->ajax_url(),
'wc_ajax_url' => WC_AJAX::get_endpoint( "test_email" ) ) );
}
add_action( 'wp_enqueue_scripts', 'kia_ajax_email_js', 20 );
/**
* AJAX callback
*
* @since 0.1
*/
function kia_ajax_email_callback() {
$mailer = WC()->mailer();
do_action( 'kia_trigger_ajax_email' );
die('ajax finished'); // this is required to terminate immediately and return a proper response
}
add_action( 'wc_ajax_test_email', 'kia_ajax_email_callback' );
/**
* Register action as one that sends emails
*
* @since 0.1
*/
function kia_ajax_email_action( $actions ){
$actions[] = 'kia_trigger_ajax_email';
return $actions;
}
add_action( 'woocommerce_email_actions', 'kia_ajax_email_action' );
/**
* Add a dummy button to product page
*
* @since 0.1
*/
function kia_ajax_email_button(){
echo '<button class="email-trigger">' . __( 'Email Trigger', 'kia-ajax-email' ). '</button>';
}
add_action('woocommerce_before_single_product_summary', 'kia_ajax_email_button');
The email class includes/class-wc-test-ajax-email.php
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* A custom Expedited Order WooCommerce Email class
*
* @since 0.1
* @extends \WC_Email
*/
class WC_Test_Ajax_Email extends WC_Email {
/**
* Set email defaults
*
* @since 0.1
*/
public function __construct() {
// set ID, this simply needs to be a unique name
$this->id = 'wc_text_ajax_email';
// this is the title in WooCommerce Email settings
$this->title = 'Test Ajax';
// this is the description in WooCommerce email settings
$this->description = 'Text emails are sent when ajax button is clicked';
// these are the default heading and subject lines that can be overridden using the settings
$this->heading = 'Test Ajax';
$this->subject = 'Test Ajax';
// these define the locations of the templates that this email should use, we'll just use the new order template since this email is similar
$this->template_html = 'emails/test.php';
$this->template_plain = 'emails/plain/test.php';
// Trigger on new paid orders
add_action( 'kia_trigger_ajax_email', array( $this, 'trigger' ) );
// Call parent constructor to load any other defaults not explicity defined here
parent::__construct();
// this sets the recipient to the settings defined below in init_form_fields()
$this->recipient = $this->get_option( 'recipient' );
// if none was entered, just use the WP admin email as a fallback
if ( ! $this->recipient )
$this->recipient = get_option( 'admin_email' );
}
/**
* Determine if the email should actually be sent and setup email merge variables
*
* @since 0.1
* @param int $order_id
*/
public function trigger() {
if ( ! $this->is_enabled() || ! $this->get_recipient() )
return;
// woohoo, send the email!
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
}
/**
* get_content_html function.
*
* @since 0.1
* @return string
*/
public function get_content_html() {
return wc_get_template_html( $this->template_html, array(
'email_heading' => $this->get_heading(),
'sent_to_admin' => false,
'plain_text' => false,
'email' => $this
),
'',
kia_ajax_email_plugin_path() . "/templates/" );
}
/**
* get_content_plain function.
*
* @since 0.1
* @return string
*/
public function get_content_plain() {
return wc_get_template_html( $this->template_plain, array(
'email_heading' => $this->get_heading(),
'sent_to_admin' => false,
'plain_text' => false,
'email' => $this
),
'',
kia_ajax_email_plugin_path() . "/templates/" );
}
/**
* Initialize Settings Form Fields
*
* @since 2.0
*/
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => 'Enable/Disable',
'type' => 'checkbox',
'label' => 'Enable this email notification',
'default' => 'yes'
),
'recipient' => array(
'title' => 'Recipient(s)',
'type' => 'text',
'description' => sprintf( 'Enter recipients (comma separated) for this email. Defaults to <code>%s</code>.', esc_attr( get_option( 'admin_email' ) ) ),
'placeholder' => '',
'default' => ''
),
'subject' => array(
'title' => 'Subject',
'type' => 'text',
'description' => sprintf( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', $this->subject ),
'placeholder' => '',
'default' => ''
),
'heading' => array(
'title' => 'Email Heading',
'type' => 'text',
'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.' ), $this->heading ),
'placeholder' => '',
'default' => ''
),
'email_type' => array(
'title' => 'Email type',
'type' => 'select',
'description' => 'Choose which format of email to send.',
'default' => 'html',
'class' => 'email_type',
'options' => array(
'plain' => __( 'Plain text', 'woocommerce' ),
'html' => __( 'HTML', 'woocommerce' ),
'multipart' => __( 'Multipart', 'woocommerce' ),
)
)
);
}
} // end \WC_Test_Ajax_Email class
the script js/script.js
jQuery(document).ready(function($) {
$(".email-trigger").on("click", function(e) {
e.preventDefault();
$.ajax({
url: kia_ajax_email.wc_ajax_url.toString(),
type: 'POST',
data: {
'whatever': 1234
},
})
.done(function(data) {
if (console && console.log) {
console.log(data);
}
});
});
});
The email templates. first templates/emails/test.php
and templates/emails/plain/test.php
<?php
/**
* Test email
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/test.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates/Emails
* @version 2.5.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @hooked WC_Emails::email_header() Output the email header
*/
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
<p><?php _e( 'A test email is being sent', 'kia-ajax-email' ); ?></p>
<?php
/**
* @hooked WC_Emails::email_footer() Output the email footer
*/
do_action( 'woocommerce_email_footer', $email );
and templates/emails/plain/test.php
<?php
/**
* Test email
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/test.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates/Emails
* @version 2.5.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
echo "= " . $email_heading . " =\n\n";
echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
_e( 'A test email is being sent', 'kia-ajax-email' );
echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) );
Going forward
This sends an email when a button is clicked. You will need to modify where that button goes, and because it is kind of slow (or seems so on my local setup) I would definitely recommend some kind of spinner/notification that the action is happening. You'll also need to customize what data is sent via ajax and how that ends up in the templates. This is just a proof of concept.
WC_Custom_Email
class. Where's the trigger? Why do you need to override themail()
method? What's your AJAX look like? And your AJAX callback? Please edit your question in lieu of trying to post code in the comments. – helgatheviking