2

I am very new to Wordpress and Woocommerce. Below is some part of my code that I am using to add a custom metabox to order admin single pages:

add_action('add_meta_boxes', 'new_meta_box');

function new_meta_box(){
add_meta_box(
    'new_meta_box',
    'New Meta Box',
    'new_meta_box_button',
    'shop_order',
    'side',
    'high'
);
}

function new_meta_box_button(){

submit_button('New Meta Box Button', 'primary','new_meta_box_button');      

global $post;
$order_id = $post->ID;
$order = wc_get_order($order_id);
$order_number = absint($order->get_order_number());

button_action($order);  
}   

add_action('save_post','button_action');

function button_action($order){
 //unbale to access $order here

if(!isset($_POST['new_meta_box_button'])){
        return;
    }

 get_value($order);
 }

function get_value($order){

//unable to access $order here
// var_dump($order) shows nothing
$order_id = $order->get_order_number();

$json = get_json($order_id);

$option_value = get_option( 'option_meta_key' );

}

In this code, if I use the custom function get_the_order() under get_order_details, it works. My problem, is that I need to access the WC_Order object $order in various functions throughout the file.

This is all on the admin end with an already existing order so no new order is being created. I need certain details of the order in one function like shipping details and billing details in another function...so on and so forth.

What am I doing wrong? How can I access the order object from an external custom function?

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
coderGeek
  • 176
  • 2
  • 12
  • From my understanding wc_get_order($order_num) returns the WC_Order object. So you could try something like $order = get_the_order() and then $order->get_some_order_detail(); https://stackoverflow.com/questions/39401393/how-to-get-woocommerce-order-details – user3325126 Oct 03 '18 at 01:03
  • @LoicTheAztec - $post->ID always gives the Id of the current post. Using $order = new WC_Order ($post->ID) was not working so I had to use wc_get_order(); – coderGeek Oct 03 '18 at 01:42
  • @LoicTheAztec - Yes but it only works with the function that is called in add_action()....is it wc_get_order() that has restricted scope or something else? – coderGeek Oct 03 '18 at 01:47
  • @LoicTheAztec: Hi, I have updated the code. I am basically working with an order on the admin end. I need to post some order details to the database when the submit_button('New Button') is clicked. I am not sure what hooks are available for that so I am using save_post. Your answer to https://stackoverflow.com/questions/37772912/woocommerce-add-custom-metabox-to-admin-order-page was very helpful! – coderGeek Oct 03 '18 at 13:44

2 Answers2

2

You are still not explaining what you want to do with this metabox in Order admin pages

The following code based on your code, will show you the way (with a real functional $order):

// Add a new custom meta box to Admin single order pages
add_action('add_meta_boxes', 'new_meta_box');
    function new_meta_box(){
    add_meta_box( 'new_meta_box',
        __('New Meta Box', 'woocommerce'),
        'new_meta_box_content',
        'shop_order', 'side', 'high'
    );
}

// The content of this new metabox
function new_meta_box_content(){
    global $post; // <=== Alway at the beginning

    // Get an instance of the WC_Order Object
    $order = wc_get_order( $post->ID );

    // TESTING an external custom function (with the WC_Order object as argument)
    echo get_formatted_order_key( $order );

    // Example (testing): Displaying a text field
    woocommerce_wp_text_input( array(
        'id'          => '_my_text_field1',
        'type'        => 'text',
        'label'       => __( 'My field 1', 'woocommerce' ),
        'placeholder' => __( 'My placeholder text 1', 'woocommerce' ),
        'description' => __( 'My Custom description 1: your explanations.', 'woocommerce' ),
        'desc_tip'    => true,
    ) );

    // The nonce field (security): Always when you submit data from custom form fields
    echo '<input type="hidden" name="my_fields_nonce" value="' . wp_create_nonce() . '">';

    // Not really needed as the default "Update" button does the same.
    submit_button(__('Submit'), 'primary', 'new_meta_box_button' ); //  <=== To be removed
}

// Saving the text field value only from shop orders post type admin pages
add_action('save_post_shop_order','save_new_meta_box_content');
function save_new_meta_box_content( $post_id ){
    if ( ! isset( $_POST[ 'my_fields_nonce' ] ) ) {
        return $post_id;
    }

    if ( ! wp_verify_nonce( $_REQUEST[ 'my_fields_nonce' ] ) ) {
        return $post_id;
    }

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return $post_id;
    }

    if ( ! current_user_can( 'edit_shop_order', $post_id ) ) {
        return $post_id;
    }

    // Everything is secured, we can save the value
    if ( isset( $_POST[ '_my_text_field1' ] ) ) {
        update_post_meta( $post_id, '_my_text_field1', sanitize_text_field( $_POST[ '_my_text_field1' ] ) );
    }
}


// Custom external function with the WC_Order object as argument
function get_formatted_order_key( $order ){
    if( is_a($order, 'WC_Order') && $order_key = $order->get_order_key() ){
        $output = '<p><strong>Order key: </strong>'.$order_key.'</p>';
    } else {
        $output = '<p style="font-weight:bold; color:red;">Something is wrong!</p>';
    }
    return $output;
}

Code goes in function.php file of your active child theme (active theme). Tested and works.

enter image description here

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • 1
    Thanks for your answer. That does help a lot. The only thing is I need the behavior of the button to be similar to the "Add" button in the order notes metabox. So, I don't want the entire page to reload, when the button is clicked. Instead, it can just show the processing spinner and then update the page with a message. What hook do I use for that? Will I use add_action or add_filter for that? Thanks! – coderGeek Oct 04 '18 at 13:37
  • i have the same q. – Mostafa Aug 10 '19 at 19:57
0

The WC_ORDER contains the all billing and shipping details.

magegaga.com
  • 500
  • 3
  • 7
  • I am working on the admin end with an already existing order. I need to use different details of the order in different functions....say all the shipping details in one function and all the billing details in another function. – coderGeek Oct 03 '18 at 01:44