Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save damiencarbery/5ea0884d13e7d41c52682252c2fdcad0 to your computer and use it in GitHub Desktop.
Save damiencarbery/5ea0884d13e7d41c52682252c2fdcad0 to your computer and use it in GitHub Desktop.
Add extra order info to WooCommerce details table - Use a custom metabox for extra order information that will be added to the end of the details table. https://www.damiencarbery.com/2024/05/add-extra-order-info-to-woocommerce-details-table/
<?php
/*
Plugin Name: WooCommerce - Add extra order info to details table
Plugin URI: https://www.damiencarbery.com/2024/05/add-extra-order-info-to-woocommerce-details-table/
Description: Use a custom metabox for extra order information that will be added to the end of the details table.
Author: Damien Carbery
Author URI: https://www.damiencarbery.com
Version: 0.1.20240521
WC tested to: 8.9.1
Requires Plugins: woocommerce
*/
defined( 'ABSPATH' ) || exit;
use Automattic\WooCommerce\Utilities\OrderUtil;
// Declare that this plugin supports WooCommerce HPOS.
add_action( 'before_woocommerce_init', function() {
if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
}
} );
class AdditionalInfoInDetailsTable {
public function __construct() {
$this->init();
}
private function init() {
add_action( 'woocommerce_loaded', array( $this, 'load_ai_meta_box_hooks' ) );
add_action( 'woocommerce_email_before_order_table', array( $this, 'check_for_order_completed_email' ), 10, 4 );
add_action( 'woocommerce_order_details_after_order_table_items', array( $this, 'add_additional_order_info_to_view_order' ) );
}
private function get_meta_key() {
return 'additional_info';
}
private function get_nonce_name() {
return 'dcwd_additional_info_nonce';
}
private function get_textarea_name() {
return 'additional_info';
}
// Verify the nonce and that this is not a post revision or autosave.
private function user_can_save( $post_id, $nonce ) {
$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
$is_valid_nonce = ( isset( $_POST[ $nonce ] ) && wp_verify_nonce( $_POST[ $nonce ], plugin_basename( __FILE__ ) ) );
return ! ( $is_autosave || $is_revision ) && $is_valid_nonce;
}
public function load_ai_meta_box_hooks() {
add_action( 'add_meta_boxes', array( $this, 'add_additional_info_meta_box' ) );
// Use different hook to save meta data when HPOS active.
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
add_action( 'woocommerce_process_shop_order_meta', array( $this, 'save_additional_info_meta_box_data' ) );
}
else {
add_action( 'save_post', array( $this, 'save_additional_info_meta_box_data' ) );
}
}
public function add_additional_info_meta_box() {
// Use different screen paaramater to show meta box when HPOS active.
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
add_meta_box( 'dcwd_additional_info_meta_box', 'Addition information', array( $this, 'display_additional_info_meta_box' ), 'woocommerce_page_wc-orders', 'normal', 'default' );
}
else {
add_meta_box( 'dcwd_additional_info_meta_box', 'Additional information', array( $this, 'display_additional_info_meta_box' ), 'shop_order', 'normal', 'default' );
}
}
// Render custom meta box.
public function display_additional_info_meta_box( $post ) {
wp_nonce_field( plugin_basename(__FILE__), $this->get_nonce_name() );
// Get the order object to retrieve the meta.
if ( $post instanceof WC_Order ) {
$order_id = $post->get_id();
} else {
$order_id = $post->ID;
}
$order = wc_get_order( $order_id );
$additional_info = $order->get_meta( $this->get_meta_key(), true );
?>
<style>
.dcwd-additional-info label { font-weight: bold; padding-bottom: 0.5em; }
.dcwd-additional-info textarea { width: 100%; margin-bottom: 1em; margin-top: 1em; }
</style>
<div class="dcwd-additional-info">
<label for="<?php echo $this->get_textarea_name(); ?>">Additional info for order</label>
<textarea name="<?php echo $this->get_textarea_name(); ?>" rows="4" cols="80"><?php esc_attr_e( $additional_info ); ?></textarea>
</div>
<?php
}
// Sanitize and store the updated info.
function save_additional_info_meta_box_data( $order_id ) {
if ( $this->user_can_save( $order_id, $this->get_nonce_name() ) ) {
$order = wc_get_order( $order_id );
if ( $order ) {
$save_needed = false;
if ( isset( $_POST[ $this->get_textarea_name() ] ) && 0 < strlen( trim( $_POST[ $this->get_textarea_name() ] ) ) ) {
// This strips out tags so html links will be removed (but not bare urls).
$additional_info = sanitize_textarea_field( trim( $_POST[ $this->get_textarea_name() ] ) );
$order->update_meta_data( $this->get_meta_key(), $additional_info );
$save_needed = true;
}
if ( $save_needed ) {
$order->save_meta_data();
}
}
}
}
// Check for Completed Order email before hooking in function to echo the info.
public function check_for_order_completed_email( $order, $sent_to_admin, $plain_text, $email ) {
if ( 'customer_completed_order' == $email->id ) {
add_filter( 'woocommerce_get_order_item_totals', array( $this, 'add_additional_order_info_after_details' ), 10, 3 );
}
}
// Add the info to the Completed Order email.
public function add_additional_order_info_after_details( $total_rows, $order_obj, $tax_display ) {
$order = wc_get_order( $order_obj );
$additional_info = $order->get_meta( $this->get_meta_key(), true );
if ( ! empty( $additional_info ) ) {
$info = array();
$info['order_info'] = array(
'label' => nl2br( esc_html( $additional_info ) ),
'value' => '',
);
return array_merge( $info, $total_rows );
}
return $total_rows;
}
// Add the info to the My Account/View Order area.
public function add_additional_order_info_to_view_order( $order ) {
$additional_info = $order->get_meta( $this->get_meta_key(), true );
if ( ! empty( $additional_info ) ) {
echo '<tr><td colspan="2">', nl2br( esc_html( $additional_info ) ), '</td></tr>';
}
}
}
$AdditionalInfoInDetailsTable = new AdditionalInfoInDetailsTable();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment