-->

WooCommerce admin order edit save post

2020-06-20 08:31发布

问题:

In WooCommerce, when I submit, how to catch a custom select field added in the order edit admin pages?

I have added this custom select field in the file class-wc-meta-box-order-data.php. I get this:

But I dont know how to catch or to save $_POST['vendor']

I have tried to add $_POST['vendor'] in wp-admin/post.phpbut it doesn't work.

This is the code that I have added:

    <select class="wc-customer-search" id="customer_user" name="customer_user" data-placeholder="<?php esc_attr_e( 'Guest', 'woocommerce' ); ?>" data-allow_clear="true">
                                <option value="<?php echo esc_attr( $user_id ); ?>" selected="selected"><?php echo htmlspecialchars( $user_string ); ?></option>
                            </select>
                            <!--/email_off-->
                        </p>
                   <p> <label for="order_status">供應商: </label>
                    <select name="vendor">
  <?php 
           global $wpdb;
   $user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->users" );
    for($i=1;$i<=$user_count;$i++){
    $user_info = get_userdata($i);

    if (implode(', ', $user_info->roles)=='vendor')
echo "<option value=".$user_info->user_login.">$user_info->user_login</option>";
    }
                    ?>
</select></p> 

How can I get the submitted value and how can I save it?

回答1:

Overriding core files is something prohibited for developers. So this is not the correct way to do it.

The way to do it is using the available hooks in the source code, instead of overriding this core files, as you will loose everything when the plugin will be updated.

  1. Replace all original core files
  2. Add this code instead (I have make some minor necessary changes).

Here is the replacement code + a hook to save the data to the order meta data:

add_action( 'woocommerce_admin_order_data_after_order_details', 'custom_code_after_order_details', 10, 1 );
function custom_code_after_order_details ( $order ) {


    $value = get_post_meta( $order->get_id(), '_vendor', true );
    ?>
    <p> <label for="order_status">供應商: </label>
    <select name="vendor">
    <?php  global $wpdb;
        $user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->users" );
        echo '<option value="">Select a vendor</option>';
        for($i=1;$i<=$user_count;$i++){
            $user_info = get_userdata($i);
            if (implode(', ', $user_info->roles)=='customer'){
                $user_login = $user_info->user_login;
                $selected = $value == $user_login ? 'selected' : '';
                echo '<option '.$selected.' value="'.$user_login.'">'.$user_login.'</option>';
            }
        }
    ?>
    </select></p>
    <input type="hidden" name="custom_select_field_nonce" value="<?php echo wp_create_nonce(); ?>">
    <?php
}

add_action( 'save_post', 'save_custom_code_after_order_details', 10, 1 );
function save_custom_code_after_order_details( $post_id ) {

    // We need to verify this with the proper authorization (security stuff).

    // Check if our nonce is set.
    if ( ! isset( $_POST[ 'custom_select_field_nonce' ] ) ) {
        return $post_id;
    }
    $nonce = $_REQUEST[ 'custom_select_field_nonce' ];

    //Verify that the nonce is valid.
    if ( ! wp_verify_nonce( $nonce ) ) {
        return $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 $post_id;
    }

    // Check the user's permissions.
    if ( 'page' == $_POST[ 'post_type' ] ) {

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

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

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

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code is tested and works.