phpwordpresswoocommerceordershook-wordpress

"Undefined index: post_type" when using save_post hook on Woocommerce orders


I am getting an error in my debug.log, for some code that saves my custom field on checkout. I can't seem to find what's wrong:

PHP Notice:  Undefined index: post_type in /wp-content/themes/theme-child/functions.php on line 857

And here are my code:

// Saving
add_action( 'save_post', 'tcg_save_meta_box_data' );
function tcg_save_meta_box_data( $post_id ) {

    // Only for shop order
    if ( 'shop_order' != $_POST[ 'post_type' ] )
        return $post_id;

    // Check if our nonce is set (and our cutom field)
    if ( ! isset( $_POST[ 'tracking_box_nonce' ] ) && isset( $_POST['tracking_box'] ) )
        return $post_id;

    $nonce = $_POST[ 'tracking_box_nonce' ];

    // Verify that the nonce is valid.
    if ( ! wp_verify_nonce( $nonce ) )
        return $post_id;

    // Checking that is not an autosave
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
        return $post_id;

    // Check the user’s permissions (for 'shop_manager' and 'administrator' user roles)
    if ( ! current_user_can( 'edit_shop_order', $post_id ) && ! current_user_can( 'edit_shop_orders', $post_id ) )
        return $post_id;

    // Saving the data
    update_post_meta( $post_id, 'Other notes', sanitize_text_field( $_POST[ 'tracking_box' ] ) );
}

Anyone who can spot the error?


Solution

  • The $_POST['post_type'] is not available in the hook save_post… This action hook has 3 available arguments: $post_id, $post and $update. So instead use:

    add_action( 'save_post', 'tcg_save_meta_box_data', 10, 3 );
    function tcg_save_meta_box_data( $post_id, $post, $update ) {
    
        // Only for shop order
        if ( 'shop_order' != $post->post_type )
            return $post_id;
    
        // ...
    

    Better: Or use directly the composite hook save_post_shop_order this way:

    add_action( 'save_post_shop_order', 'tcg_save_meta_box_data', 10, 3 );
    function tcg_save_meta_box_data( $post_id, $post, $update ) {
        // Check if our nonce is set (and our custom field)
        if ( ! isset( $_POST[ 'tracking_box_nonce' ] ) && isset( $_POST['tracking_box'] ) )
            return $post_id;
    
        $nonce = $_POST[ 'tracking_box_nonce' ];
    
        // Verify that the nonce is valid.
        if ( ! wp_verify_nonce( $nonce ) )
            return $post_id;
    
        // Checking that is not an autosave
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
            return $post_id;
    
        // User capability check: Check if the current user can edit an order 
        if ( ! current_user_can( 'edit_shop_order', $post_id ) )
            return $post_id;
    
        // Saving the data
        update_post_meta( $post_id, 'Other notes', sanitize_text_field( $_POST[ 'tracking_box' ] ) );
    }
    

    Code goes in function.php file of your active child theme (active theme). It should better work.