I want developing a shipping plugin for Woocommerce
I want to send parameters to a third party api
Tell me how to do is the right
Name Phone mail is required.
It's my code
English is not good, please forgive me.
How do I fix this?
Thank you.
<?php
/*
Plugin Name: Ship
Plugin URI: http://woothemes.com/woocommerce
Description: Ship-Jay Hsu
Version: 1.0.0
Author: JayHsu
Author URI: http://
*/
/**
* Check if WooCommerce is active
*/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
function EG($order){
global $woocommerce; global $post;
$billing_first_name = $woocommerce->session->get('billing_first_name');
$billing_last_name = $woocommerce->session->get('billing_last_name');
$cardurl = 'http://myshoptest.net.php?'.
'&Pay_zg=41' .
'&Rvg2c=1' .
'&Od_sob=' .$order_name.
'&Pur_name=' .$billing_first_name.$billing_last_name.
'&Mobile_number=' .$order->billing_phone.
'&Email=' .$order->billing_email.
'&Roturl_status=' . 'woook'.
'&Roturl=' . $Vk.
'&Remark=woocommerce';
header("Location: $cardurl");
exit();
}
function SFNM_init() {
if ( ! class_exists( 'WC_SFNM' ) ) {
class WC_SFNM extends WC_Shipping_Method {
/**
* Constructor for your shipping class
*
* #access public
* #return void
*/
public function __construct() {
$this->id = 'SFNM'; // Id for your shipping method. Should be uunique.
$this->method_title = __( 'Ship' ); // Title shown in admin
$this->method_description = __( 'Ship' ); // Description shown in admin
$this->enabled = "yes"; // This can be added as an setting but for this example its forced enabled
$this->title = "Ship"; // This can be added as an setting but for this example its forced.
$this->init_form_fields();
$this->init();
}
/**
* Init your settings
*
* #access public
* #return void
*/
function init() {
// Load the settings API
$this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings
$this->init_settings(); // This is part of the settings API. Loads settings you previously init.
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* calculate_shipping function.
*
* #access public
* #param mixed $package
* #return void
*/
public function calculate_shipping( $package ) {
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => '60',
'calc_tax' => 'per_item'
);
// Register the rate
$this->add_rate( $rate );
}
}
}
}
add_action( 'woocommerce_shipping_init', 'SFNM_init' );
add_action( 'woocommerce_thankyou','EG');
function add_SFNM_method( $methods ) {
$methods[] = 'WC_SFNM';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'add_SFNM_method' );
}
?>
Related
I have two shipping zones. For one of them, I need a custom shipping method. I added a new method. I can add it from the drop-down list in woocommerce->Shipping->Location. I want users to be able to choose by using a radio button in the cart section. At this moment this method is not working at all. This shipping method is implemented as a plugin.
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
function costs_specified_init() {
if ( ! class_exists( 'Shipping_Costs_Will_BE_Specified' ) ) {
class Shipping_Costs_Will_BE_Specified extends WC_Shipping_Method {
/**
* Constructor for your shipping class
*
* #access public
* #return void
*/
public function __construct() {
$this->id = 'specified_price'; // Id for your shipping method. Should be uunique.
$this->method_title = __( 'Specified shipping price' ); // Title shown in admin
$this->method_description = __( 'Used to specify shipping price' ); // Description shown in admin
$this->enabled = "yes"; // This can be added as an setting but for this example its forced enabled
$this->title = "Specified shipping price"; // This can be added as an setting but for this example its forced.
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->init();
}
/**
* Init your settings
*
* #access public
* #return void
*/
function init() {
// Load the settings API
$this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings
$this->init_settings(); // This is part of the settings API. Loads settings you previously init.
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* calculate_shipping function.
*
* #access public
* #param mixed $package
* #return void
*/
public function calculate_shipping( $package = array() ) {
$rate = array(
'label' => $this->title,
'cost' => '0',
'calc_tax' => 'per_item'
);
// Register the rate
$this->add_rate( $rate );
}
}
}
}
add_action( 'woocommerce_shipping_init', 'costs_specified_init' );
function add_your_shipping_method( $methods ) {
$methods['specified_price'] = 'Shipping_Costs_Will_BE_Specified';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'add_your_shipping_method' );
}
``
For my clients site to integrate with a third party I need to create multiple shipping methods (flat rate) with unique names. I followed the woocommerce turorial to create a plugin to add a shipping zone and then found some instructions to make it support zones and it worked. I'm now trying to make the plugin create multiple shipping zones but although they seem to appear in zones - clicking on them doesn't add them to the zone.
e.g. they appear here but don't do anything when clicked
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
function your_shipping_method_init() {
if ( ! class_exists( 'WA_Metro_Shipping_Method' ) ) {
class WA_Metro_Shipping_Method extends WC_Shipping_Method {
/**
* Constructor for your shipping class
*
* #access public
* #return void
*/
public function __construct( $instance_id = 0 ) {
$this->id = 'wa_metro_flat'; // Id for your shipping method. Should be uunique.
$this->method_title = __( 'WA Metro Flat Rate' ); // Title shown in admin
$this->method_description = __( 'Flat rate shipping for WA Metro Postcodes' ); // Description shown in admin
$this->enabled = "yes"; // This can be added as an setting but for this example its forced enabled
$this->title = "WA Metro Flat Rate"; // This can be added as an setting but for this example its forced.
$this->instance_id = absint( $instance_id );
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->init();
}
/**
* Init your settings
*
* #access public
* #return void
*/
function init() {
// Load the settings API
$this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings
$this->init_settings(); // This is part of the settings API. Loads settings you previously init.
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
public function is_available( $package ){
return true;
}
/**
* calculate_shipping function.
*
* #access public
* #param mixed $package
* #return void
*/
public function calculate_shipping( $package ) {
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => '8.59',
'calc_tax' => 'per_item'
);
// Register the rate
$this->add_rate( $rate );
}
}
}
/***************************************************/
if ( ! class_exists( 'WA_Regional_Shipping_Method' ) ) {
class WA_Regional_Shipping_Method extends WC_Shipping_Method {
/**
* Constructor for your shipping class
*
* #access public
* #return void
*/
public function __construct( $instance_id = 0 ) {
$this->id = 'vic_metro_flat'; // Id for your shipping method. Should be uunique.
$this->method_title = __( 'VIC Metro Flat Rate' ); // Title shown in admin
$this->method_description = __( 'Flat rate shipping for VIC Metro Postcodes' ); // Description shown in admin
$this->enabled = "yes"; // This can be added as an setting but for this example its forced enabled
$this->title = "VIC Metro Flat Rate"; // This can be added as an setting but for this example its forced.
$this->instance_id = absint( $instance_id );
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->init();
}
/**
* Init your settings
*
* #access public
* #return void
*/
function init() {
// Load the settings API
$this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings
$this->init_settings(); // This is part of the settings API. Loads settings you previously init.
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
public function is_available( $package ){
return true;
}
/**
* calculate_shipping function.
*
* #access public
* #param mixed $package
* #return void
*/
public function calculate_shipping( $package ) {
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => '8.59',
'calc_tax' => 'per_item'
);
// Register the rate
$this->add_rate( $rate );
}
}
}
/***************************************************/
if ( ! class_exists( 'VIC_Metro_Shipping_Method' ) ) {
class VIC_Metro_Shipping_Method extends WC_Shipping_Method {
/**
* Constructor for your shipping class
*
* #access public
* #return void
*/
public function __construct( $instance_id = 0 ) {
$this->id = 'wa_regional_flat'; // Id for your shipping method. Should be uunique.
$this->method_title = __( 'WA Regional Flat Rate' ); // Title shown in admin
$this->method_description = __( 'Flat rate shipping for WA Metro Postcodes' ); // Description shown in admin
$this->enabled = "yes"; // This can be added as an setting but for this example its forced enabled
$this->title = "WA Regional Flat Rate"; // This can be added as an setting but for this example its forced.
$this->instance_id = absint( $instance_id );
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->init();
}
/**
* Init your settings
*
* #access public
* #return void
*/
function init() {
// Load the settings API
$this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings
$this->init_settings(); // This is part of the settings API. Loads settings you previously init.
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* calculate_shipping function.
*
* #access public
* #param mixed $package
* #return void
*/
public function calculate_shipping( $package ) {
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => '18.57',
'calc_tax' => 'per_item'
);
// Register the rate
$this->add_rate( $rate );
}
}
}
/***************************************************/
}
add_action( 'woocommerce_shipping_init', 'your_shipping_method_init' );
function add_your_shipping_method( $methods ) {
$methods['your_shipping_method'] = 'WA_Metro_Shipping_Method';
$methods['your_shipping_method_2'] = 'WA_Regional_Shipping_Method';
$methods['your_shipping_method_3'] = 'VIC_Metro_Shipping_Method';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'add_your_shipping_method' );
}
I've figured out why it wasn't working after reading the comments on this blog post
https://wpruby.com/shipping-method-for-woocommerce-development-tutorial/
Basically where I was setting the id for the method
$this->id = 'wa_metro_flat';
I wasn't using the correct method name in this bit, I was using the function name
$methods['your_shipping_method'] = 'WA_Metro_Shipping_Method';
It should be
$methods['your_shipping_method'] = 'wa_metro_flat';
Actually it should be
$methods['wa_metro_flat'] = 'WA_Metro_Shipping_Method';
I'm attempting to remove an action and add it with a different priority.
Below are all the code snippets that assist in generating a Message:
Include required frontend files
private function frontend_includes() {
require_once( $this->get_plugin_path() . '/includes/wc-memberships-template-functions.php' );
require_once( $this->get_plugin_path() . '/includes/class-wc-memberships-shortcodes.php' );
WC_Memberships_Shortcodes::initialize();
$this->frontend = $this->load_class( '/includes/frontend/class-wc-memberships-frontend.php', 'WC_Memberships_Frontend' );
$this->checkout = $this->load_class( '/includes/frontend/class-wc-memberships-checkout.php', 'WC_Memberships_Checkout' );
$this->restrictions = $this->load_class( '/includes/frontend/class-wc-memberships-restrictions.php', 'WC_Memberships_Restrictions' );
}
Get the product purchasing restricted message
/**
* #param int $post_id Optional. Defaults to current post.
* #return string
*/
public function get_product_purchasing_restricted_message( $post_id = null ) {
if ( ! $post_id ) {
global $post;
$post_id = $post->ID;
}
$products = $this->get_products_that_grant_access( $post_id );
$message = $this->get_restriction_message( 'product_purchasing_restricted', $post_id, $products );
/**
* Filter the product purchasing restricted message
*
* #since 1.0.0
* #param string $message The restriction message
* #param int $product_id ID of the product being restricted
* #param array $products Array of product IDs that grant access to this product
*/
return apply_filters( 'wc_memberships_product_purchasing_restricted_message', $message, $post_id, $products );
}
Restriction class, handles content restriction on frontend
class WC_Memberships_Restrictions {
/** #var array associative array of content conditions for current user **/
private $user_content_access_conditions;
/** #var array of post IDs that content restriction has been applied to **/
private $content_restriction_applied = array();
/** #var string Product content restriction password helper **/
private $product_restriction_password = null;
/** #var bool Product thumbnail removed helper **/
private $product_thumbnail_restricted = false;
public function __construct() {
// Desired action to remove and re-prioritize
add_action( 'woocommerce_single_product_summary', array( $this, 'single_product_purchasing_restricted_message' ), 30 );
}
}
I literally just need to alter the priority to 15 from 30 in the action of the WC_Memberships_Restrictions class. The issue is that there's no clear way to call the removal. Any suggestions?
Well the code you provided shows that the instance of the WC_Memberships_Restrictions class is stored in the main class' restrictions property.
$this->restrictions = $this->load_class( '/includes/frontend/class-wc-memberships-restrictions.php', 'WC_Memberships_Restrictions' );
From there I just had to look up how to access the instance of the main Membership class, from the bottom of the main plugin file you see:
/**
* Returns the One True Instance of Memberships
*
* #since 1.0.0
* #return WC_Memberships
*/
function wc_memberships() {
return WC_Memberships::instance();
}
This means that now to access the instance of the restrictions class we need to access the main class's restriction property. While that sounds clear as mud, basically it means this:
wc_memberships()->restrictions
Knowing this, we can known remove and add actions from that class:
function so_41431558_change_hook_priority(){
if( function_exists( 'wc_memberships' ) ){
remove_action( 'woocommerce_single_product_summary', array( wc_memberships()->restrictions, 'single_product_purchasing_restricted_message' ), 30 );
add_action( 'woocommerce_single_product_summary', array( wc_memberships()->restrictions, 'single_product_purchasing_restricted_message' ), 15 );
}
}
add_action( 'woocommerce_single_product_summary', 'so_41431558_change_hook_priority', 1 );
I am a fairly new PHP developer and what I am trying to create is a custom endpoint for the "myaccount" page . I am trying to create a "Add Guest" end point. I am finding it very difficult to find any documentation online. What I have done so far is used this git hub repo
https://gist.github.com/neilgee/13ac00c86c903c4ab30544b2b76c483c/a43701564ab696e1586e2879591c890b67a5f1bf#file-woo-endpoints-order-php
I created these files and put them in the plugins/woocommerce/includes directory. But they seem to take no effect. Have i put them in the correct directory? Am I soppose to call these classes somewhere else ? I have no idea where I going wrong. Can some please educate me on this matter.
<?php
/*
* Add custom endpoint that appears in My Account Page - WooCommerce 2.6
* Ref - https://gist.github.com/claudiosmweb/a79f4e3992ae96cb821d3b357834a005#file-custom-my-account-endpoint-php
*/
class My_Custom_My_Account_Endpoint {
/**
* Custom endpoint name.
*
* #var add_students_details
*/
public static $endpoint = 'add_students_details';
/**
* Plugin actions.
*/
public function __construct() {
// Actions used to insert a new endpoint in the WordPress.
add_action( 'init', array( $this, 'add_endpoints' ) );
add_filter( 'query_vars', array( $this, 'add_query_vars' ), 0 );
// Change the My Accout page title.
add_filter( 'the_title', array( $this, 'endpoint_title' ) );
// Insering your new tab/page into the My Account page.
add_filter( 'woocommerce_account_menu_items', array( $this, 'new_menu_items' ) );
add_action( 'woocommerce_account_' . self::$endpoint . '_endpoint', array( $this, 'endpoint_content' ) );
}
/**
* Register new endpoint to use inside My Account page.
*
* #see https://developer.wordpress.org/reference/functions/add_rewrite_endpoint/
*/
public function add_endpoints() {
add_rewrite_endpoint( self::$endpoint, EP_ROOT | EP_PAGES );
}
/**
* Add new query var.
*
* #param array $vars
* #return array
*/
public function add_query_vars( $vars ) {
$vars[] = self::$endpoint;
return $vars;
}
/**
* Set endpoint title.
*
* #param string $title
* #return string
*/
public function endpoint_title( $title ) {
global $wp_query;
$is_endpoint = isset( $wp_query->query_vars[ self::$endpoint ] );
if ( $is_endpoint && ! is_admin() && is_main_query() && in_the_loop() && is_account_page() ) {
// New page title.
$title = __( 'My Stuff', 'woocommerce' );
remove_filter( 'the_title', array( $this, 'endpoint_title' ) );
}
return $title;
}
/**
* Insert the new endpoint into the My Account menu.
*
* #param array $items
* #return array
*/
public function new_menu_items( $items ) {
// Remove the logout menu item.
$logout = $items['customer-logout'];
unset( $items['customer-logout'] );
// Insert your custom endpoint.
$items[ self::$endpoint ] = __( 'My Stuff', 'woocommerce' );
// Insert back the logout item.
$items['customer-logout'] = $logout;
return $items;
}
/**
* Endpoint HTML content.
*/
public function endpoint_content() {
wc_get_template( 'myaccount/navigation.php' ); ?>
<div class="woocommerce-MyAccount-content">
<p>Hello World! - custom field can go here</p>
</div>
<?php
}
/**
* Plugin install action.
* Flush rewrite rules to make our custom endpoint available.
*/
public static function install() {
flush_rewrite_rules();
}
}
new My_Custom_My_Account_Endpoint();
// Flush rewrite rules on plugin activation.
register_activation_hook( __FILE__, array( 'My_Custom_My_Account_Endpoint', 'install' ) );
But they seem to take no effect. Have i put them in the correct directory? Am I soppose to call these classes somewhere else ? I have no idea where I going wrong. Can some please educate me on this matter.
First thing, you created a class, but you never loaded that file or initiated the class. The best way to do this would be in your own plugin.
Second, you have to add the add_rewrite_endpoint() to the install function. Otherwise, it doesn't know to register the new endpoint and your rewrite rules are flushed, but end up exactly the same as they were before... which creates some 404 errors.
Third, recent WooCommerce provides a filter for the endpoint title. And the content doesn't need to reproduce the My Account div or navigation.
Tested and working:
<?php
/**
* Plugin Name: WC Custom Endpoint
* Plugin URI: http://stackoverflow.com/questions/38784599/woocommerce-custom-end-points
* Description: A custom endpoint
* Version: 0.1.0
* Author: Kathy Darling
* Author URI: http://kathyisawesome.com
* Text Domain: wc_custom_endpoint
* Domain Path: /languages
* Requires at least: 4.6.0
* Tested up to: 4.6.0
*
* Copyright: © 2016 Kathy Darling.
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
/**
* The Main WC_Custom_Endpoint class
**/
if ( ! class_exists( 'WC_Custom_Endpoint' ) ) :
class WC_Custom_Endpoint {
const VERSION = '0.1.0';
/**
* Custom endpoint name.
*/
public static $endpoint = 'add_students_details';
/**
* #var WC_Custom_Endpoint - the single instance of the class
* #since 0.1.0
*/
protected static $instance = null;
/**
* Plugin Directory
*
* #since 0.1.0
* #var string $dir
*/
public $dir = '';
/**
* Plugin URL
*
* #since 0.1.0
* #var string $url
*/
public $url = '';
/**
* Main WC_Custom_Endpoint Instance
*
* Ensures only one instance of WC_Custom_Endpoint is loaded or can be loaded.
*
* #static
* #see WC_Custom_Endpoint()
* #return WC_Custom_Endpoint - Main instance
* #since 0.1.0
*/
public static function instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof WC_Custom_Endpoint ) ) {
self::$instance = new WC_Custom_Endpoint();
}
return self::$instance;
}
public function __construct(){
$this->dir = plugin_dir_path(__FILE__);
$this->url = plugin_dir_url(__FILE__);
// Load translation files
add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
// Actions used to insert a new endpoint in the WordPress.
add_action( 'init', array( $this, 'add_endpoints' ) );
add_filter( 'query_vars', array( $this, 'add_query_vars' ), 0 );
// Insering your new tab/page into the My Account page.
add_filter( 'woocommerce_account_menu_items', array( $this, 'new_menu_items' ) );
add_action( 'woocommerce_endpoint_' . self::$endpoint . '_title', array( $this, 'endpoint_title' ) );
add_action( 'woocommerce_account_' . self::$endpoint . '_endpoint', array( $this, 'endpoint_content' ) );
}
/*-----------------------------------------------------------------------------------*/
/* Localization */
/*-----------------------------------------------------------------------------------*/
/**
* Make the plugin translation ready
*
* #return void
* #since 1.0
*/
public function load_plugin_textdomain() {
load_plugin_textdomain( 'wc-custom-endpoint' , false , dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
}
/*-----------------------------------------------------------------------------------*/
/* Endpoint */
/*-----------------------------------------------------------------------------------*/
/**
* Register new endpoint to use inside My Account page.
*
* #see https://developer.wordpress.org/reference/functions/add_rewrite_endpoint/
*/
public function add_endpoints() {
add_rewrite_endpoint( self::$endpoint, EP_ROOT | EP_PAGES );
}
/**
* Add new query var.
*
* #param array $vars
* #return array
*/
public function add_query_vars( $vars ) {
$vars[] = self::$endpoint;
return $vars;
}
/*-----------------------------------------------------------------------------------*/
/* Display */
/*-----------------------------------------------------------------------------------*/
/**
* Set endpoint title.
*
* #return string
*/
public function endpoint_title() {
return __( 'My Stuff', 'wc_custom_endpoint' );
}
/**
* Insert the new endpoint into the My Account menu.
*
* #param array $items
* #return array
*/
public function new_menu_items( $items ) {
// Remove the logout menu item.
$logout = $items['customer-logout'];
unset( $items['customer-logout'] );
// Insert your custom endpoint.
$items[ self::$endpoint ] = __( 'My Stuff', 'wc_custom_endpoint' );
// Insert back the logout item.
$items['customer-logout'] = $logout;
return $items;
}
/**
* Endpoint HTML content.
*/
public function endpoint_content() { ?>
<p>Hello World! - custom wc_get_template() can go here</p>
<?php
}
/*-----------------------------------------------------------------------------------*/
/* Activation */
/*-----------------------------------------------------------------------------------*/
/**
* Plugin install action.
* Flush rewrite rules to make our custom endpoint available.
*/
public static function install() {
WC_Custom_Endpoint()->add_endpoints();
flush_rewrite_rules();
}
/**
* Plugin install action.
* Flush rewrite rules to make our custom endpoint available.
*/
public static function uninstall() {
flush_rewrite_rules();
}
} //end class: do not remove or there will be no more guacamole for you
endif; // end class_exists check
/**
* Returns the main instance of WC_Custom_Endpoint to prevent the need to use globals.
*
* #since 1.0
* #return WC_Custom_Endpoint
*/
function WC_Custom_Endpoint() {
return WC_Custom_Endpoint::instance();
}
// Launch the whole plugin
add_action( 'woocommerce_loaded', 'WC_Custom_Endpoint' );
// register activation hook
register_activation_hook( __FILE__, array( 'WC_Custom_Endpoint', 'install' ) );
register_deactivation_hook( __FILE__, array( 'WC_Custom_Endpoint', 'uninstall' ) );
I want to add a extra email filed on woocommerce checkout page in the shipping area and send a order copy to that email, is it possible to do?
Was trying for quit long time to solve this but couldn't find a solution. Hope anyone can help me on this
Ah yes, I had forgotten that I posted that. Here is the complete, updated plugin. Newer versions of WooCommerce require the email recipients to be a comma-separated spring. The old version of my plugin was returning an array, which WooCommerce could not process.
<?php
/*
Plugin Name: WooCommerce Shipping Email
Plugin URI: https://gist.github.com/helgatheviking/d2975aa4d190a5b55922#
Description: Add a shipping email field to checkout and notify of new orders
Version: 1.0.1
Author: Kathy Darling
Author URI: http://kathyisawesome.com
Requires at least: 4.0
Tested up to: 4.0
Copyright: © 2014 Kathy Darling.
License: GNU General Public License v3.0
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
/**
* The Main WC_Shipping_Email class
**/
if ( ! class_exists( 'WC_Shipping_Email' ) ) :
class WC_Shipping_Email {
/**
* #var WC_Shipping_Email - the single instance of the class
* #since 1.0
*/
protected static $_instance = null;
/**
* Main WC_Shipping_Email Instance
*
* Ensures only one instance of WC_Shipping_Email is loaded or can be loaded.
*
* #static
* #see WC_Shipping_Email()
* #return WC_Shipping_Email - Main instance
* #since 1.0
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Cloning is forbidden.
*
* #since 1.0
*/
public function __clone() {
_doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'woocommerce-mix-and-match' ), '2.0' );
}
/**
* Unserializing instances of this class is forbidden.
*
* #since 1.0
*/
public function __wakeup() {
_doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'mix-and-match' ), '2.0' );
}
/**
* WC_Shipping_Email Constructor
*
* #access public
* #return WC_Shipping_Email
* #since 1.0
*/
public function __construct() {
$this->id = 'email';
$this->meta = '_shipping_email';
$this->label = __( 'Shipping Email', 'woocommerce-shipping-email' );
// add email field to checkout
add_filter( 'woocommerce_shipping_fields' , array( $this, 'add_shipping_fields' ) );
add_filter( 'woocommerce_admin_shipping_fields' , array( $this, 'admin_shipping_fields' ) );
// add recipient to specific emails
add_filter( 'woocommerce_email_recipient_customer_processing_order' , array( $this, 'add_recipient' ), 20, 2 );
add_filter( 'woocommerce_email_recipient_customer_completed_order' , array( $this, 'add_recipient' ), 20, 2 );
add_filter( 'woocommerce_email_recipient_customer_note' , array( $this, 'add_recipient' ), 20, 2 );
// display meta key in order overview
add_action( 'woocommerce_order_details_after_customer_details' , array( $this, 'after_customer_details' ) );
// display meta key in email
add_action( 'woocommerce_before_template_part' , array( $this, 'before_email_addresses' ), 10, 4 );
}
/*-----------------------------------------------------------------------------------*/
/* Plugin Functions */
/*-----------------------------------------------------------------------------------*/
/**
* Add email to front-end shipping fields
*
* #var array $fields
* #return array
* #since 1.0
*/
function add_shipping_fields( $fields ) {
$fields['shipping_' . $this->id] = array(
'label' => $this->label,
'required' => true,
'class' => array( 'form-row-first' ),
'validate' => array( 'email' ),
);
return $fields;
}
/**
* Add email to Admin Order overview
*
* #var array $fields
* #return array
* #since 1.0
*/
function admin_shipping_fields( $fields ) {
$fields[$this->id] = array(
'label' => $this->label
);
return $fields;
}
/**
* Add recipient to emails
*
* #var string $email
* #return string
* #since 1.0
*/
function add_recipient( $email, $order ) {
$additional_email = get_post_meta( $order->id, $this->meta, true );
if( $additional_email && is_email( $additional_email )){
if( is_array( $email ) ){
$email = explode( ',', $email );
array_push( $email, $additional_email );
$email = implode( ',', $email );
} elseif( is_string( $email ) ){
$email .= "," . $additional_email;
}
}
return $email;
}
/**
* Display meta in my-account area Order overview
*
* #var object $order
* #return null
* #since 1.0
*/
public function after_customer_details( $order ){
$value = get_post_meta( $order->id, $this->meta, true );
if( $value ){
echo '<dt>' . $this->label . ':</dt><dd>' . $value . '</dd>';
}
}
/**
* Display meta in my-account area Order overview
*
* #var array $fields
* #return array
* #since 1.0
*/
public function before_email_addresses( $template_name, $template_path, $located, $args ){
if( $template_name == 'emails/email-addresses.php' && isset( $args['order' ] ) && ( $value = get_post_meta( $args['order']->id, $this->meta, true ) ) ){
if ( isset( $args['plain_text'] ) && $args['plain_text'] ){
echo $this->label . ': ' . $value . "\n";
} else {
echo '<p><strong>' . $this->label . ':</strong> ' . $value . '</p>';
}
}
}
} //end class: do not remove or there will be no more guacamole for you
endif; // end class_exists check
/**
* Returns the main instance of WC_Shipping_Email to prevent the need to use globals.
*
* #since 2.0
* #return WooCommerce
*/
function WC_Shipping_Email() {
return WC_Shipping_Email::instance();
}
// Launch the whole plugin
WC_Shipping_Email();
NB: This only sends to the shipping email for the customer_processing_order, customer_completed_order, and customer_note emails.