2

I found the below code the other day, and now my client wants two more fields. If I add it again to my snippet plugin it says “Cannot redeclare function set_custom_edit_shop_order_columns.”. Could someone kindly help me to change the code with two more custom fields?

I have changed custom_column to courier_reference and want another text field tracking_number and one more is shipping_date with a date picker rather than a text box.

Any help is appreciated.

//from::https://codex.wordpress.org/Plugin_API/Action_Reference/manage_posts_custom_column

// For displaying in columns.

add_filter( 'manage_edit-shop_order_columns', 'set_custom_edit_shop_order_columns' );
function set_custom_edit_shop_order_columns($columns) {
    $columns['custom_column'] = __( 'Custom Column', 'your_text_domain' );
    return $columns;
}

// Add the data to the custom columns for the order post type:
add_action( 'manage_shop_order_posts_custom_column' , 'custom_shop_order_column', 10, 2 );
function custom_shop_order_column( $column, $post_id ) {
    switch ( $column ) {

        case 'custom_column' :
            echo esc_html( get_post_meta( $post_id, 'custom_column', true ) );
            break;

    }
}

// For display and saving in order details page.
add_action( 'add_meta_boxes', 'add_shop_order_meta_box' );
function add_shop_order_meta_box() {

    add_meta_box(
        'custom_column',
        __( 'Custom Column', 'your_text_domain' ),
        'shop_order_display_callback',
        'shop_order'
    );

}

// For displaying.
function shop_order_display_callback( $post ) {

    $value = get_post_meta( $post->ID, 'custom_column', true );

    echo '<textarea style="width:100%" id="custom_column" name="custom_column">' . esc_attr( $value ) . '</textarea>';
}

// For saving.
function save_shop_order_meta_box_data( $post_id ) {

    // If this is an autosave, our form has not been submitted, so we don't want to do anything.
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }

    // Check the user's permissions.
    if ( isset( $_POST['post_type'] ) && 'shop_order' == $_POST['post_type'] ) {
        if ( ! current_user_can( 'edit_shop_order', $post_id ) ) {
            return;
        }
    }

    // Make sure that it is set.
    if ( ! isset( $_POST['custom_column'] ) ) {
        return;
    }

    // Sanitize user input.
    $my_data = sanitize_text_field( $_POST['custom_column'] );

    // Update the meta field in the database.
    update_post_meta( $post_id, 'custom_column', $my_data );
}

add_action( 'save_post', 'save_shop_order_meta_box_data' );
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Ashley
  • 131
  • 11

1 Answers1

2

Updated... You just need to have multiple different slugs in the same functions. For your desired 3 custom fields use the following:

// Add columns to admin orders table.
add_filter( 'manage_edit-shop_order_columns', 'set_custom_edit_shop_order_columns' );
function set_custom_edit_shop_order_columns($columns) {
    $columns['courier_reference'] = __( 'Courier reference', 'woocommerce' );
    $columns['tracking_number'] = __( 'Tracking number', 'woocommerce' );
    $columns['shipping_date'] = __( 'Shipping date', 'woocommerce' );
    return $columns;
}

// Add the data to the custom columns for the order post type:
add_action( 'manage_shop_order_posts_custom_column' , 'custom_shop_order_column', 10, 2 );
function custom_shop_order_column( $column, $post_id ) {
    switch ( $column ) {

        case 'courier_reference' :
            echo esc_html( get_post_meta( $post_id, 'courier_reference', true ) );
            break;

        case 'tracking_number' :
            echo esc_html( get_post_meta( $post_id, 'tracking_number', true ) );
            break;

        case 'shipping_date' :
            echo esc_html( get_post_meta( $post_id, 'shipping_date', true ) );
            break;

    }
}

// Add a metabox.
add_action( 'add_meta_boxes', 'add_shop_order_meta_box' );
function add_shop_order_meta_box() {

    add_meta_box(
        'custom_meta_box',
        __( 'Tracking information', 'woocommerce' ),
        'shop_order_content_callback',
        'shop_order'
    );

}

// For displaying metabox content
function shop_order_content_callback( $post ) {

    // Textarea Field
    $courier_reference = get_post_meta( $post->ID, 'courier_reference', true );

    echo '<p>' . __( 'Courier reference', 'woocommerce' ) . '<br>
    <textarea style="width:100%" id="courier_reference" name="courier_reference">' . esc_attr( $courier_reference ) . '</textarea></p>';

    // Text field
    $tracking_number = get_post_meta( $post->ID, 'tracking_number', true );
    echo '<p>' . __( 'Tracking number', 'woocommerce' ) . '<br>
    <input type="text" style="width:100%" id="tracking_number" name="tracking_number" value="' . esc_attr( $tracking_number ) . '"></p>';

    // Date picker field
    $shipping_date = get_post_meta( $post->ID, 'shipping_date', true );

    echo '<p>' . __( 'shipping_date', 'woocommerce' ) . '<br>
    <input type="date" style="width:100%" id="shipping_date" name="shipping_date" value="' . esc_attr( $shipping_date ) . '"></p>';
}

// For saving the metabox data.
add_action( 'save_post_shop_order', 'save_shop_order_meta_box_data' );
function save_shop_order_meta_box_data( $post_id ) {

    // If this is an autosave, our form has not been submitted, so we don't want to do anything.
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }

    // Check the user's permissions.
    if ( ! current_user_can( 'edit_shop_order', $post_id ) ) {
        return;
    }


    // Make sure that 'shipping_date' is set.
    if ( isset( $_POST['courier_reference'] ) ) {

        // Update the meta field in the database.
        update_post_meta( $post_id, 'courier_reference', sanitize_textarea_field( $_POST['courier_reference'] ) );
    }

    // Make sure that 'tracking_number' it is set.
    if ( isset( $_POST['tracking_number'] ) ) {

        // Update the meta field in the database.
        update_post_meta( $post_id, 'tracking_number', sanitize_text_field( $_POST['tracking_number'] ) );
    }

    // Make sure that 'shipping_date' is set.
    if ( isset( $_POST['shipping_date'] ) ) {

        // Update the meta field in the database.
        update_post_meta( $post_id, 'shipping_date', sanitize_text_field( $_POST['shipping_date'] ) );
    }
}

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

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thanks very much for this! I have put it in my snippets plugin and it is creating a 'Tracking Information' box in my orders page, however the box is empty and doesn't contain the three boxes (2 text boxes and a date picker box). I'm useless at coding and cant see what is wrong! – Ashley Apr 28 '20 at 19:44
  • @Ashley I have tested and updated my code… Now it works just as you expect. – LoicTheAztec Apr 28 '20 at 20:02
  • That's great, thanks so much for your help, really appreciated! – Ashley Apr 28 '20 at 20:05
  • Hi, sorry, one more thing, is there a way to making the shipping date box with a simple datepicker input? – Ashley Apr 28 '20 at 20:25
  • @Ashley I have changed ` – LoicTheAztec Apr 28 '20 at 21:15
  • 1
    :D I've been googling and reading and fiddling with the code... sometimes it really is simple when you know how, haha. thanks again! – Ashley Apr 28 '20 at 21:19
  • Hi, so sorry, I just noticed one thing. I just set up the fields to appear in columns on the Order Admin page, and entered values in to each of the boxes to test. They all appear on the order admin page fine, but for some reason the value in the first textarea field disappears ((although it is still there in the Order Admin table). The other two are fine. Not sure if you have the same result when you tested there? – Ashley Apr 28 '20 at 22:02
  • @Ashley On my side it works just fine… I don't see what can be wrong. – LoicTheAztec Apr 28 '20 at 22:10
  • No worries, I will do more testing on other orders. As it is bringing the value in to the Order Admin page I can live with it! Thanks again – Ashley Apr 29 '20 at 06:44
  • Works well with Woocommerce 4.4. Is there a way to add info from these fileds in this code to the My account >> Order pages and to the Order Tracking page? – soldier99 Aug 20 '20 at 15:54
  • From the `$order` object you can get those fields values using `$courier_reference = $order->get_meta('courier_reference');` and `$tracking_number = $order->get_meta('tracking_number');` and `$shipping_date = $order->get_meta('shipping_date');`… Then you need to find the correct hooks to display this data where you like. – LoicTheAztec Aug 20 '20 at 16:59