Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save damiencarbery/0e4d5f451ced33b402a152c1a1da0d40 to your computer and use it in GitHub Desktop.
Save damiencarbery/0e4d5f451ced33b402a152c1a1da0d40 to your computer and use it in GitHub Desktop.
Add extra product info to WooCommerce details table - Use a custom metabox for extra product information that will be added to the details table. https://www.damiencarbery.com/2024/05/add-extra-product-info-to-woocommerce-details-table/
<?php
/*
Plugin Name: WooCommerce - Add extra product info to details table
Plugin URI: https://www.damiencarbery.com/2024/05/add-extra-product-info-to-woocommerce-details-table/
Description: Use a custom metabox for extra product information that will be added to the details table.
Author: Damien Carbery
Author URI: https://www.damiencarbery.com
Version: 0.1.20240524
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 AdditionalProductInfoToDetailsTable {
public function __construct() {
$this->init();
}
private function init() {
add_action( 'woocommerce_loaded', array( $this, 'load_product_meta_box_hooks' ) );
add_action( 'woocommerce_email_before_order_table', array( $this, 'check_for_order_completed_email' ), 10, 4 );
add_action( 'woocommerce_order_details_before_order_table', array( $this, 'check_for_my_account_area' ) );
}
private function get_meta_key() {
return 'extra_info';
}
private function get_nonce_name() {
return 'dcwd_extra_info_nonce';
}
private function get_textarea_name() {
return 'product_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_product_meta_box_hooks() {
add_action( 'add_meta_boxes', array( $this, 'add_product_info_meta_box' ) );
add_action( 'save_post', array( $this, 'save_product_info_meta_box_data' ) );
}
public function add_product_info_meta_box() {
add_meta_box( 'dcwd_additional_info_meta_box', 'Information for order email', array( $this, 'display_product_info_meta_box' ), 'product', 'normal', 'default' );
}
// Render custom meta box.
public function display_product_info_meta_box( $post ) {
wp_nonce_field( plugin_basename(__FILE__), $this->get_nonce_name() );
$product_id = $post->ID;
$product_info = get_post_meta( $product_id, $this->get_meta_key(), true );
?>
<style>
.dcwd-product-info label { font-weight: bold; padding-bottom: 0.5em; }
.dcwd-product-info textarea { width: 100%; margin-bottom: 1em; margin-top: 1em; }
</style>
<div class="dcwd-product-info">
<label for="<?php echo $this->get_textarea_name(); ?>">Additional info for order emails</label>
<textarea name="<?php echo $this->get_textarea_name(); ?>" rows="4" cols="80"><?php esc_attr_e( $product_info ); ?></textarea>
</div>
<?php
}
// Sanitize and store the updated info.
public function save_product_info_meta_box_data( $product_id ) {
if ( $this->user_can_save( $product_id, $this->get_nonce_name() ) ) {
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).
$product_info = sanitize_textarea_field( trim( $_POST[ $this->get_textarea_name() ] ) );
update_post_meta( $product_id, $this->get_meta_key(), $product_info );
}
}
}
// 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_action( 'woocommerce_order_item_meta_end', array( $this, 'add_product_info_after_product_details' ), 10, 4 );
}
}
public function check_for_my_account_area( $order ) {
// This function is called when in My Account/Orders/View Order so can now run the function to add the product info.
// Maybe check if order is complete.
add_action( 'woocommerce_order_item_meta_end', array( $this, 'add_product_info_after_product_details' ), 10, 4 );
}
public function add_product_info_after_product_details( $item_id, $item, $order, $plain_text ) {
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
$product_info = get_post_meta( $product_id, $this->get_meta_key(), true );
if ( ! empty( $product_info ) ) {
echo '<br>', nl2br( esc_html( $product_info ) );
}
}
}
$AdditionalProductInfoToDetailsTable = new AdditionalProductInfoToDetailsTable();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment