13
votes

I'm searching and trying it for 2 days with no success, please help.

I want to filter woocommerce orders to add additional details from db to order details page based on product attribute but I can't find the right woocommerce action/filter hook for this task. Here suppose I've variable $is_customized = false;

If $is_customized == true then I need to add custom data from database to orders detail page.

NOTE: I don't want to add additional meta box instead I want to change order detail table for:

  • Replacing the default Product image with the image stored in database and,
  • Adding a div containing custom attributes below product name.

I've all these values in my variables but I can't figure out which action hook should I use.

I've attached an image for clarification.

enter image description here

Just need to know if I can change / filter these order results and how ?

I appreciate for your time and help. Thanks

1
Like any other custom post type columns are handled via manage $post type posts columns and manage $post type posts custom column. And in the case of orders the post type is shop_order. - helgatheviking
Nevermind, I just looked more closely at your screenshot and it isn't what I was thinking. That said, it is a metabox, so at worst you could remove it, and add a modified version in its stead. - helgatheviking
means there is no action/filter available to filter these results or customize it instead of rewriting the whole module ? - Haider Saeed
manage_edit-shop_order_columns and manage_shop_order_posts_custom_column these both add extra column to orders table but I want to add column in order edit page where the details of the specific order is listed. - Haider Saeed
You can see the hooks you have at your disposal in html-order-items.php and html-order-item.php - helgatheviking

1 Answers

17
votes

Here's a start on how to display some extra data on the woocommerce_before_order_itemmeta hook:

add_action( 'woocommerce_before_order_itemmeta', 'so_32457241_before_order_itemmeta', 10, 3 );
function so_32457241_before_order_itemmeta( $item_id, $item, $_product ){
    echo '<p>bacon</p>';
}

I don't know how you are saving your data, so I can't make more a more precise suggestion. Keep in mind that immediately following that hook, anything you've saved as order item meta will automatically display.

Filtering the image is more difficult. I've found this gist as a start, but it requires some custom conditional logic as you don't want to filter the thumbnail everywhere, but only in orders.

Edit: Currently the best I can do for filtering the item thumbnails:

add_filter( 'get_post_metadata', 'so_32457241_order_thumbnail', 10, 4 );
function so_32457241_order_thumbnail( $value, $post_id, $meta_key, $single ) {
    // We want to pass the actual _thumbnail_id into the filter, so requires recursion
    static $is_recursing = false;
    // Only filter if we're not recursing and if it is a post thumbnail ID
    if ( ! $is_recursing && $meta_key === '_thumbnail_id' ) {
        $is_recursing = true; // prevent this conditional when get_post_thumbnail_id() is called
        $value = get_post_thumbnail_id( $post_id );
        $is_recursing = false;
        $value = apply_filters( 'post_thumbnail_id', $value, $post_id ); // yay!
        if ( ! $single ) {
            $value = array( $value );
        }
    }
    return $value;
}


add_filter( 'post_thumbnail_id', 'so_custom_order_item_thumbnail', 10, 2 );
function so_custom_order_item_thumbnail( $id, $post_id ){
    if( is_admin() ){
        $screen = get_current_screen();
        if( $screen->base == 'post' && $screen->post_type == 'shop_order' ){
            // this gets you the shop_order $post object
            global $post; 

            // no really *good* way to check post item, but could possibly save 
            // some kind of array in the order meta
            $id = 68;
        } 
    }
    return $id;
}