I am using [Plugin: Visualizer: Charts and Graphs]
In this plugin there is class
class Visualizer_Module_Frontend extends Visualizer_Module {
const NAME = __CLASS__;
private $_charts = array();
public function __construct( Visualizer_Plugin $plugin ) {
parent::__construct( $plugin );
$this->_addAction( 'wp_enqueue_scripts', 'enqueueScripts' );
$this->_addShortcode( 'visualizer', 'renderChart' );
// add do_shortocde hook for widget_text filter
if ( !has_filter( 'widget_text', 'do_shortcode' ) ) {
add_filter( 'widget_text', 'do_shortcode' );
}
// add do_shortcode hook for term_description filter
if ( !has_filter( 'term_description', 'do_shortcode' ) ) {
add_filter( 'term_description', 'do_shortcode' );
}
}
public function enqueueScripts() {
wp_register_script( 'visualizer-google-jsapi', '//www.google.com/jsapi', array(), null, true );
wp_register_script( 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array( 'visualizer-google-jsapi', 'jquery' ), Visualizer_Plugin::VERSION, true );
}
public function renderChart( $atts ) {
$atts = shortcode_atts( array(
'id' => false, // chart id
'class' => false, // chart class
'series' => false, // series filter hook
'data' => false, // data filter hook
'settings' => false, // data filter hook
), $atts );
// if empty id or chart does not exists, then return empty string
if ( !$atts['id'] || !( $chart = get_post( $atts['id'] ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) {
return '';
}
$id = 'visualizer-' . $atts['id'];
$class = apply_filters( Visualizer_Plugin::FILTER_CHART_WRAPPER_CLASS, $atts['class'], $atts['id'] );
$class = !empty( $class ) ? ' class="' . $class . '"' : '';
$type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true );
// faetch and update settings
$settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
if ( empty( $settings['height'] ) ) {
$settings['height'] = '400';
}
// handle series filter hooks
$series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type );
if ( !empty( $atts['series'] ) ) {
$series = apply_filters( $atts['series'], $series, $chart->ID, $type );
}
// handle settings filter hooks
$settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type );
if ( !empty( $atts['settings'] ) ) {
$settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type );
}
// handle data filter hooks
$data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type );
if ( !empty( $atts['data'] ) ) {
$data = apply_filters( $atts['data'], $data, $chart->ID, $type );
}
// add chart to the array
$this->_charts[$id] = array(
'type' => $type,
'series' => $series,
'settings' => $settings,
'data' => $data,
);
// enqueue visualizer render and update render localizations
wp_enqueue_script( 'visualizer-render' );
wp_localize_script( 'visualizer-render', 'visualizer', array( 'charts' => $this->_charts ) );
return '<div id="' . $id . '"' . $class . '></div>';
} }
I want to extent this class so that i can override the function renderChart().
But I want to do this with another custom plugin.
Related
I am trying to create a separate download page in WordPress when the visitor clicks on a download button having link https://example.com/(any_post)/download, it will open a download page having the destination url.
What i have done?
I have created a custom field that takes link from post for this I uses below:
// Meta Box Class: DownloadLinkMetaBox
// Get the field value: $metavalue = get_post_meta( $post_id, $field_id, true );
class DownloadLinkMetaBox{
private $screen = array(
'post',
);
private $meta_fields = array(
array(
'label' => 'Download Link',
'id' => 'download_id',
'type' => 'text',
)
);
public function __construct() {
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
add_action( 'save_post', array( $this, 'save_fields' ) );
}
public function add_meta_boxes() {
foreach ( $this->screen as $single_screen ) {
add_meta_box(
'DownloadLink',
__( 'DownloadLink', '' ),
array( $this, 'meta_box_callback' ),
$single_screen,
'normal',
'default'
);
}
}
public function meta_box_callback( $post ) {
wp_nonce_field( 'DownloadLink_data', 'DownloadLink_nonce' );
$this->field_generator( $post );
}
public function field_generator( $post ) {
$output = '';
foreach ( $this->meta_fields as $meta_field ) {
$label = '<label for="' . $meta_field['id'] . '">' . $meta_field['label'] . '</label>';
$meta_value = get_post_meta( $post->ID, $meta_field['id'], true );
if ( empty( $meta_value ) ) {
if ( isset( $meta_field['default'] ) ) {
$meta_value = $meta_field['default'];
}
}
switch ( $meta_field['type'] ) {
default:
$input = sprintf(
'<input %s id="%s" name="%s" type="%s" value="%s">',
$meta_field['type'] !== 'color' ? 'style="width: 100%"' : '',
$meta_field['id'],
$meta_field['id'],
$meta_field['type'],
$meta_value
);
}
$output .= $this->format_rows( $label, $input );
}
echo '<table class="form-table"><tbody>' . $output . '</tbody></table>';
}
public function format_rows( $label, $input ) {
return '<tr><th>'.$label.'</th><td>'.$input.'</td></tr>';
}
public function save_fields( $post_id ) {
if ( ! isset( $_POST['DownloadLink_nonce'] ) )
return $post_id;
$nonce = $_POST['DownloadLink_nonce'];
if ( !wp_verify_nonce( $nonce, 'DownloadLink_data' ) )
return $post_id;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
foreach ( $this->meta_fields as $meta_field ) {
if ( isset( $_POST[ $meta_field['id'] ] ) ) {
switch ( $meta_field['type'] ) {
case 'email':
$_POST[ $meta_field['id'] ] = sanitize_email( $_POST[ $meta_field['id'] ] );
break;
case 'text':
$_POST[ $meta_field['id'] ] = sanitize_text_field( $_POST[ $meta_field['id'] ] );
break;
}
update_post_meta( $post_id, $meta_field['id'], $_POST[ $meta_field['id'] ] );
} else if ( $meta_field['type'] === 'checkbox' ) {
update_post_meta( $post_id, $meta_field['id'], '0' );
}
}
}
}
if (class_exists('DownloadLinkMetabox')) {
new DownloadLinkMetabox;
};
That takes link perfectly and also able to show on front but not able to create another page.
Below code used to show in frontend
add_action( 'generate_after_entry_header', 'wpsh_single_posts_custom_meta_fields', 9 );
function wpsh_single_posts_custom_meta_fields(){
$post_id = get_the_ID();
$post = get_post( $post_id );
$download_id = get_post_meta( $post->ID, 'download_id' );
if( $download_id ) { ?>
<div class="wp-block-buttons aligncenter">
<div class="wp-block-button">
<a style='text-transform: uppercase;' href="<?php the_permalink();?>download/" class="wp-block-button__link has-vivid-cyan-blue-background-color download ripple">
<i class="material-icons">
<svg class="icon" fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none" />
<path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z" />
</svg>
</i> Download</a>
</div>
</div>
<?php }
}
Above code will show button if the download id have link and the button have link example.com/any_post/download. Now here i don't know how to serve the link that the download_id holds of the post from it visits to .../download
I'm thinking to create a template page that serve the link but not able to do
in your functions:
Once you have added all your code make sure to flush your rewrite rules by going to: Settings > Permalinks and clicking 'save changes'
Set your rewrite rules:
function custom_add_rewrite_rule(){
$posts = get_posts( array( 'numberposts' => -1, 'post_type' => 'post') );
if( $posts ){
foreach($posts as $post ){
add_rewrite_rule(
$post->post_name . '/download/?$',
'index.php?name=' . $post->post_name . '&post_action=download&post_id=' . $post->ID,
'top'
);
}
}
}
add_action('init', 'custom_add_rewrite_rule');
add your query_vars:
function add_query_vars_filter( $vars ){
$vars[] = "post_action";
$vars[] = "post_id";
return $vars;
}
add_filter( 'query_vars', 'add_query_vars_filter' );
then include your custom template:
function include_custom_template($template){
if( get_query_var('post_action') && get_query_var('post_action') == 'download'){
$template = get_template_directory() ."/download.php";
}
return $template;
}
add_filter('template_include', 'include_custom_template');
and finally make a file called download.php in your theme root and call your parameters
$download_id = get_post_meta( get_query_var('post_id'), 'download_id' );
//Your Code
I am looking to have an action included in my functions.php file that changes the echo array from true to false in the below code:
function wc_display_item_meta( $item, $args = array() ) {
$strings = array();
$html = '';
$args = wp_parse_args(
$args,
array(
'before' => '<ul class="wc-item-meta"><li>',
'after' => '</li></ul>',
'separator' => '</li><li>',
'echo' => true,
'autop' => false,
'label_before' => '<strong class="wc-item-meta-label">',
'label_after' => ':</strong> ',
)
);
The above code is found in the WooCommerce wc-template-functions.php file found on line 3273.
How can I do this?
In includes/wc-template-functions.php, you will see that the function in there is wrapped in a if ( ! function_exists( 'wc_display_item_meta' ) ) { conditional.
So redefine the same function in functions.php file of the active child theme (or active theme) and your custom function will override the existing.
Note: A function can only be reassigned this way once.
So you get:
/**
* Display item meta data.
*
* #since 3.0.0
* #param WC_Order_Item $item Order Item.
* #param array $args Arguments.
* #return string|void
*/
function wc_display_item_meta( $item, $args = array() ) {
$strings = array();
$html = '';
$args = wp_parse_args(
$args,
array(
'before' => '<ul class="wc-item-meta"><li>',
'after' => '</li></ul>',
'separator' => '</li><li>',
'echo' => false,
'autop' => false,
'label_before' => '<strong class="wc-item-meta-label">',
'label_after' => ':</strong> ',
)
);
foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) {
$value = $args['autop'] ? wp_kses_post( $meta->display_value ) : wp_kses_post( make_clickable( trim( $meta->display_value ) ) );
$strings[] = $args['label_before'] . wp_kses_post( $meta->display_key ) . $args['label_after'] . $value;
}
if ( $strings ) {
$html = $args['before'] . implode( $args['separator'], $strings ) . $args['after'];
}
$html = apply_filters( 'woocommerce_display_item_meta', $html, $item, $args );
if ( $args['echo'] ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $html;
} else {
return $html;
}
}
Missing WP_List_Table Entries Screenshot Here
I'm trying to populate a list table in WordPress using WP_List_Table with country and state codes from WooCommerce, but it seems that either :display(), :prepare-items() or :column_default is failing me. Been staring myself blind for hours and I can't track down what's happening.
The class setup looks as follows:
<?php
if ( ! class_exists( 'WP_List_Table' ) ) {
require_once ABSPATH . 'wp-admin/includes/screen.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}
class My_List_Table extends WP_List_Table {
public function __construct() {
parent::__construct(
array(
'singular' => __( 'state', 'my-text-domain' ),
'plural' => __( 'states', 'my-text-domain' ),
'ajax' => false,
)
);
}
public function get_columns() {
$columns = array(
'cb' => '<input type="checkbox" />',
'col_state_name' => __( 'Region Name', 'my-text-domain' ),
'col_state_id' => __( 'Region Code', 'my-text-domain' ),
);
return $columns;
}
public function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'col_state_id':
case 'col_state_name':
return $item[ $column_name ];
default:
return $item;
}
}
public function my_load_states() {
if ( get_option( 'my_countries' ) && get_option( 'my_current_country' ) && get_option( 'my_states_' . get_option( 'my_current_country' ) ) ) {
$states = get_option( 'my_states_' . get_option( 'my_current_country' ) );
update_option( 'myplugin', true );
return $states;
} else {
$states = WC()->countries->get_states( get_option( 'my_current_country' ) );
if ( is_array( $states ) ) {
return $states;
} else {
update_option( 'myplugin', true );
return '';
}
}
}
public function get_states() {
$data = array();
if ( get_option( 'my_states_' . get_option( 'my_current_country' ) ) && ! empty( get_option( 'my_states_' . get_option( 'my_current_country' ) ) ) && get_option( 'my_country' ) && in_array( get_option( 'my_current_country' ), get_option( 'my_countries' ), true ) ) {
$states = get_option( 'my_states_' . get_option( 'my_current_country' ) );
update_option( 'myplugin', true );
} else {
$states = $this->my_load_states();
}
if ( ! empty( $states ) ) {
foreach ( $states as $code => $name ) {
$temp = array(
'col_state_name' => $name,
'col_state_id' => $code,
);
array_push( $data, $temp );
}
return $data;
} else {
return '';
}
}
public function prepare_items() {
$this->_column_headers = $this->get_column_info();
$this->process_bulk_action();
$data = $this->get_states();
if ( ! empty( $data ) && is_array( $data ) ) {
usort( $data, array( &$this, 'usort_reorder' ) );
$per_page = count( $data );
$total_items = count( $data );
}
$current_page = $this->get_pagenum();
if ( is_array( $data ) && count( $data ) > 1 ) {
$found_data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );
} else {
$found_data = $data;
$total_items = 0;
}
$this->set_pagination_args(
array(
'total_items' => $total_items,
'per_page' => $per_page,
)
);
$this->items = $found_data;
}
public function no_items() {
esc_html_e( 'No states avaliable.', 'my-text-domain' );
}
}
I'm initiating things through this:
<?php
class My_Admin {
...
public function my_add_menu_item() {
add_submenu_page(
'woocommerce',
'Locations',
'Locations',
'manage_options',
'my_states',
array( $this, 'my_settings_page' ),
);
}
public function my_settings_page() {
$slp_obj = new My_List_Table();
$slp_obj->prepare_items();
$slp_obj->display();
}
}
?>
In the previous version ( >5 ) of WordPress the plugin was working correctly. When I transferred it to an updated WordPress (v5.xx) website.
It was giving me an error "visaBooking class does not have init method".
I changed the hooks initialization to init() from _construct(). Now the error is gone but the shortcodes are not working anymore?
function visaBooking() {
return visaBooking::instance();
}
add_action( 'plugins_loaded', 'visaBooking' );
class visaBooking{
private static $_instance = null;
private $categories = array();
private $pricing = array();
private $discount = array();
private $insurance = array();
private $pricingDetails = array();
public static function instance() {
if ( is_null( self::$_instance ) )
self::$_instance = new self();
return self::$_instance;
} // End instance()
public function __construct(){
# Read countries json file
$countriesFile = plugin_dir_url( __FILE__ ).'countries.json';
$countriesFileResponse = wp_remote_get( $countriesFile );
$countriesFileBody = json_decode( $countriesFileResponse['body'] , true );
if( $this->isJson( $countriesFileResponse['body'] ) ){
$categories = json_decode( $countriesFileResponse['body'] , true );
if( !empty( $categories ) ){
foreach( $categories as $category ){
switch( $category['Price Type'] ){
case 'Medium':
$newCategory['medium'][] = $category['Country Codes'];
break;
case 'Expensive':
$newCategory['expensive'][] = $category['Country Codes'];
break;
case 'Cheaper':
$newCategory['cheaper'][] = $category['Country Codes'];
break;
}
}
$this->categories = $newCategory;
}
}
# Read services json file
$file = plugin_dir_url( __FILE__ ).'config.json';
$response = wp_remote_get( $file );
#$body = json_decode( $response['body'] , true );
if( $this->isJson( $response['body'] ) ){
$this->pricing = json_decode( $response['body'] , true );
}
}
public function init () {
add_action( 'template_redirect', array( $this, 'initialization' ) );
# Get price shortcode
add_shortcode( 'visa-booking-price' , array( $this, 'visaBookingPrice' ) );
# Get form shortcode
add_shortcode( 'visa-booking-form' , array( $this, 'visaBookingForm' ) );
add_filter( 'gform_pre_render', array( $this, 'modifyPricing' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueueScript') );
add_action('wp_head', array( $this, 'enqueueJs') );
add_filter( 'gform_enable_field_label_visibility_settings', '__return_true' );
add_filter('gform_replace_merge_tags', array( $this, 'replace_merge_tag_code' ), 10, 7);
add_action( 'gform_admin_pre_render', array( $this, 'add_merge_tags' ) );
add_filter( 'gform_shortcode_conditional', array( $this, 'gform_shortcode_conditional_custom' ), 10, 3 );
add_shortcode('page_number', function(){
return $_POST['page_number'];
});
add_filter( 'gform_confirmation', array( $this, 'hide_boxed' ), 10, 4 );
add_shortcode('template_header', function($args){
ob_start();
include( plugin_dir_path( __FILE__ )."email-templates/header.php");
$text = ob_get_clean();
return do_shortcode($text);
});
add_shortcode('order_details', function($args){
$temp = array(
'form_id' => 1,
'entry_id' => 1,
'isadmin' => 'false'
);
$args = array_merge( $temp, $args );
ob_start();
switch($args['type']){
case 'flight';
include( plugin_dir_path( __FILE__ )."email-templates/flight-order-details.php");
break;
case 'hotel';
include( plugin_dir_path( __FILE__ )."email-templates/hotel-order-details.php");
break;
case 'flight-hotel';
include( plugin_dir_path( __FILE__ )."email-templates/flight-hotel-order-details.php");
break;
case 'flight-hotel-insurance';
include( plugin_dir_path( __FILE__ )."email-templates/flight-hotel-insurance-order-details.php");
break;
case 'insurance';
include( plugin_dir_path( __FILE__ )."email-templates/insurance-order-details.php");
break;
}
$entry = GFAPI::get_entry( $args['entry_id'] );
$form = GFAPI::get_form( $args['form_id'] );
$text = ob_get_clean();
$text = GFCommon::replace_variables( $text, $form, $entry, false, false, false, 'html' );
return do_shortcode($text);
});
add_shortcode('template_footer', function($args){
ob_start();
include( plugin_dir_path( __FILE__ )."email-templates/footer.php");
$text = ob_get_clean();
return do_shortcode($text);
});
}
I thought it would run smoothly now but as mentioned above now the short code is not working.
I am not a php programmer, and it takes me forever to figure out why. So hopefully SO could help me out. Basically, I installed a woocommerce plugin called interfax-woocommerce, which is used to send order completion email to fax number. On the documentation, it says the plugin uses order completion template to send the fax. It does include everything on the order email template except leaving the order note field out. I believe it must have something to do with the plugin. maybe it passes the order array without including that particular order note field? I can not figure out why and how to fix it. Below is the source code of interfax plugin
if ( ! defined( 'ABSPATH' ) ) exit;
class WooCommerce_InterFax_Integration {
private $dir;
private $file;
private $assets_dir;
private $assets_url;
private $settings;
private $interfax_class;
private $username;
private $password;
private $store_fax_number;
private $template_html;
private $heading;
private $send_store_fax;
private $order;
private $fax_number;
public function __construct( $file ) {
$this->dir = dirname( $file );
$this->file = $file;
$this->assets_dir = trailingslashit( $this->dir ) . 'assets';
$this->assets_url = esc_url( trailingslashit( plugins_url( '/assets/', $file ) ) );
// Add settings link to plugin page
add_filter( 'plugin_action_links_' . plugin_basename( $this->file ), array( $this, 'add_settings_link' ) );
// Get integration settings
$this->settings = get_option( 'woocommerce_interfax_settings' );
// Only handle actions if integration is enabled
if( $this->settings['wcif_enable'] == 'yes' ) {
$this->interfax_class = 'http://ws.interfax.net/dfs.asmx?wsdl';
$this->username = $this->settings['wcif_username'];
$this->password = $this->settings['wcif_password'];
$this->store_fax_number = $this->settings['wcif_fax_number'];
$this->template_html = 'emails/customer-completed-order.php';
$this->heading = __( 'Your order is complete', 'woocommerce' );
$this->send_store_fax = true;
// Add fax number field to checkout
add_filter( 'woocommerce_checkout_fields', array( $this, 'add_checkout_field' ) );
// Send fax on selected order status (deault to 'completed' if no status is selected)
if( $this->settings['wcif_fax_status'] ) {
$fax_status = $this->settings['wcif_fax_status'];
} else {
$fax_status = 'completed';
}
add_action( 'woocommerce_order_status_' . $fax_status, array( $this, 'trigger' ) );
// Add order action to dashboard
add_filter( 'woocommerce_order_actions', array( $this, 'add_order_action' ) );
// Handle order actions
add_action( 'woocommerce_order_action_send_customer_fax', array( $this, 'process_order_action_customer' ) );
add_action( 'woocommerce_order_action_send_store_fax', array( $this, 'process_order_action_store' ) );
// Add fax number field to user profile page in WP dashboard
add_filter( 'woocommerce_customer_meta_fields', array( $this, 'add_user_meta_field' ) );
// Add fax number field to edit billing address page
add_filter( 'woocommerce_billing_fields', array( $this, 'add_address_field' ), 10, 2 );
}
// Handle localisation
$this->load_plugin_textdomain();
add_action( 'init', array( $this, 'load_localisation' ), 0 );
}
public function trigger( $order_id ) {
if ( $order_id ) {
$this->order = new WC_Order( $order_id );
// Send fax to store owner
if( $this->store_fax_number && strlen( $this->store_fax_number ) > 0 ) {
$this->send_store_fax();
}
// Send fax to customer
$this->fax_number = get_post_meta( $order_id, '_billing_fax', true );
if( $this->fax_number && strlen( $this->fax_number ) > 0 ) {
$this->send_customer_fax();
}
}
}
private function send_customer_fax() {
$interfax_client = new SoapClient( $this->interfax_class );
$params->Username = $this->username;
$params->Password = $this->password;
$params->FaxNumber = $this->fax_number;
$params->Data = $this->get_fax_content();
$params->FileType = 'HTML';
$result = $interfax_client->SendCharFax( $params );
if( isset( $result->SendCharFaxResult ) && $result->SendCharFaxResult > 0 ) {
return true;
}
return false;
}
private function send_store_fax() {
$interfax_client = new SoapClient( $this->interfax_class );
$params->Username = $this->username;
$params->Password = $this->password;
$params->FaxNumber = $this->store_fax_number;
$params->Data = $this->get_fax_content();
$params->FileType = 'HTML';
$result = $interfax_client->SendCharFax( $params );
if( isset( $result->SendCharFaxResult ) && $result->SendCharFaxResult > 0 ) {
return true;
}
return false;
}
public function get_fax_content() {
global $woocommerce;
ob_start();
$template_data = array(
'order' => $this->order,
'email_heading' => $this->heading
);
if( version_compare( $woocommerce->version, '2.1-beta-1', ">=" ) ) {
wc_get_template( $this->template_html, $template_data );
} else {
woocommerce_get_template( $this->template_html, $template_data );
}
return ob_get_clean();
}
public function add_checkout_field( $fields ) {
$fields['billing']['billing_fax'] = array(
'label' => __( 'Fax Number (including country code)', 'wc_interfax' ),
'placeholder' => _x( 'e.g. +27861234567', 'placeholder', 'wc_interfax' ),
'required' => false,
'class' => array( 'form-row' ),
'clear' => false
);
return $fields;
}
public function add_order_action( $actions ) {
$actions['send_customer_fax'] = 'Send customer fax';
$actions['send_store_fax'] = 'Send store fax';
return $actions;
}
public function process_order_action_customer( $order ) {
$this->fax_number = get_post_meta( $order->id, '_billing_fax', true );
if( $this->fax_number && strlen( $this->fax_number ) > 0 ) {
$this->order = $order;
$this->send_customer_fax();
}
}
public function process_order_action_store( $order ) {
if( $this->store_fax_number && strlen( $this->store_fax_number ) > 0 ) {
$this->order = $order;
$this->send_store_fax();
}
}
public function add_user_meta_field( $fields ) {
$fields['billing']['fields']['billing_fax'] = array(
'label' => __( 'Fax number', 'wc_interfax' ),
'description' => ''
);
return $fields;
}
public function add_address_field( $fields, $country ) {
$fields['billing_fax'] = array(
'label' => __( 'Fax Number (including country code)', 'wc_interfax' ),
'placeholder' => _x( 'e.g. +27861234567', 'placeholder', 'wc_interfax' ),
'required' => false,
'class' => array( 'form-row' ),
'clear' => true
);
return $fields;
}
public function add_settings_link( $links ) {
$settings_link = '' . __( 'Configure', 'wc_interfax' ) . '';
array_unshift( $links, $settings_link );
return $links;
}
public function load_localisation () {
load_plugin_textdomain( 'wc_interfax' , false , dirname( plugin_basename( $this->file ) ) . '/lang/' );
}
public function load_plugin_textdomain () {
$domain = 'wc_interfax';
$locale = apply_filters( 'plugin_locale' , get_locale() , $domain );
load_textdomain( $domain , WP_LANG_DIR . '/' . $domain . '/' . $domain . '-' . $locale . '.mo' );
load_plugin_textdomain( $domain , FALSE , dirname( plugin_basename( $this->file ) ) . '/lang/' );
}
Here is an example of adding the customer's note (which is the order post's "excerpt") to the bottom of all emails:
add_action( 'woocommerce_email_after_order_table' , 'so_28333042_add_customer_note' );
function so_28333042_add_customer_note( $order ){
$post = get_post( $order->id );
if( $post->post_excerpt != '' ){
echo "<strong>Customer Note:</strong><br/>" . wp_kses_post( $post->post_excerpt );
}
}
The woocommerce_email_after_order_table hook is definitely available in WooCommerce 2.3, but I think it is available in 2.2+ as well.
Alternatively, you could copy the customer-completed-order.php template into your theme and work directly on it.