Replace product “on backorder” to a custom field v

2019-07-13 02:01发布

问题:

Firstly, thanks for viewing this question. I've searched and gone through many similar questions however i've not managed to find a perfect fix.

Im setting up a website using wordpress/woocommerce, however most of our products have a set lead time therefore everything is on "back order - allow" status. Instead of showing "on backorder" on each product page, I wanted to see if it was possible to create a custom field in each product and replace the "on backorder" text to show that custom field.

Currently, i've been using the following code that just changes the text for every product however, not all products are on that specific lead time.

add_filter( 'woocommerce_get_availability', 'backorder_text', 10, 2);
function backorder_text($available) {
 return str_replace('Available on backorder', 'Approx lead time: 2-4 working weeks', $available);
}

I appreciate I would need to set up a custom field in each product with the set time, but i'm not entirely sure how to link that specfic custom field per each product to that php code (or rather, whether its actually possible).

Any help would be fantastic - even if its to tell me it can't be done!

回答1:

This can be done with the following code, that will handle products and product variation too:

// Add a custom field in admin product edit pages - inventory tab
add_action( 'woocommerce_product_options_stock_fields', 'add_product_options_stock_custom_field', 20 );
function add_product_options_stock_custom_field() {
    global $product_object, $post;

    woocommerce_wp_text_input( array(
        'id'          => '_backorder_text',
        'type'        => 'text',
        'label'       => __( 'Backorders text', 'woocommerce' ),
        'description' => __( 'Backorders text. Add a custom backorders text to be displayed when products are on backorders.', 'woocommerce' ),
        'desc_tip'    => true,
    ) );

    // jQuery: HIDE the fied if backorders are not enabled
    ?>
    <script type="text/javascript">
    jQuery( function($){
        var a = 'select#_backorders',
            b = 'p._backorder_text_field';

        if( $(a).val() === 'no' )
            $(b).hide();

        $(a).on('change blur', function(){
            if( $(a).val() === 'no' )
                $(b).hide();
            else
                $(b).show();
        });
    });
    </script>
    <?php
}

// Save the custom field value from admin product edit pages - inventory tab
add_action( 'woocommerce_process_product_meta', 'save_product_options_stock_custom_field', 20, 1 );
function save_product_options_stock_custom_field( $product_id ) {
    if ( isset( $_POST['_backorder_text'] ) )
        update_post_meta( $product_id, '_backorder_text', sanitize_text_field( $_POST['_backorder_text'] ) );
}

// Variations: Add a custom field in admin variation options inventory
add_action( 'woocommerce_variation_options_inventory', 'add_variation_settings_fields', 20, 3 );
function add_variation_settings_fields( $loop, $variation_data, $variation_post ) {

    woocommerce_wp_text_input( array(
        'id'            => '_backorder_text'.$loop,
        'name'          => '_backorder_text['.$loop.']',
        'value'         => get_post_meta( $variation_post->ID, '_backorder_text', true ),
        'type'          => 'text',
        'label'         => __( 'Backorders text', 'woocommerce' ),
        'description'   => __( 'Backorders text. Add a custom backorders text to be displayed when products are on backorders.', 'woocommerce' ),
        'desc_tip'      => true,
        'wrapper_class' => 'form-row form-row-first',
    ) );
}

// Variations: Save a custom field value from admin variation options inventory
add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
function save_variation_settings_fields( $variation_id, $i ) {
    if( isset( $_POST['_backorder_text'][$i] ) )
        update_post_meta( $variation_id, '_backorder_text', sanitize_text_field( $_POST['_backorder_text'][$i] ) );
}

add_filter( 'woocommerce_get_availability', 'custom_on_backorder_text', 10, 2 );
function custom_on_backorder_text( $availability, $product ) {
    $backorder_text = get_post_meta( $product->get_id(), '_backorder_text', true );

    if( $availability['class'] === 'available-on-backorder' && ! empty( $backorder_text ) )
        $availability['availability'] = $backorder_text;

    return $availability;
}

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

For all products (except variable products, see after) you will get:

For product variations (of a variable product):