Update a custom-field by another custom-field

2k views Asked by At

Iam working with lots of custom_fields in WordPress.

Currently Iam working with WooCommerce, I dont exactly know if my question is WP or just Woo related.

I have one custom-field setup as a select box. I can choose between several items such as:

  1. new
  2. in_stock
  3. sold_out

When I select "sold_out" and save the post/product, I not only want to save this field, but I also want to set the "_stock_status" to "outofstock".

The field "_stock_status" is an default WooCommerce field. It is also a drop-down box. You can select the values "instock" or "outofstock".

The thing is Iam working with a WooCommerce save function, its called, woocommerce_process_product_meta.

I thought that I could just run two update_post_meta function. But that doesnt work.

I tried the following, for testing, check if my custom-field is not empty. If it is NOT empty update it with the selected value, and also update the "_stock_status".

$woocommerce_select = $_POST['_my_custom_field'];

if( !empty( $woocommerce_select ) ) {
       update_post_meta( $post_id, '_my_custom_field', esc_attr( $woocommerce_select ) );
       update_post_meta( $post_id, '_stock_status', 'outofstock' );
}

With this function I can save _my_custom_field, but the _stock_status dont change.

I also tried variations of this, and other if-functions. But it seems that I just cant update that field like this way.

$woocommerce_select = $_POST['_my_custom_field'];

if( $woocommerce_select == 'sold_out' ) {
               update_post_meta( $post_id, '_my_custom_field', esc_attr( $woocommerce_select ) );
               update_post_meta( $post_id, '_stock_status', 'outofstock' );
} else {
               update_post_meta( $post_id, '_my_custom_field', esc_attr( $woocommerce_select ) );
}

Dont know what Iam doing wrong here, maybe somebody can point me to it.

Thanks, Mo


Update: Function/Hook added:

function woo_add_custom_general_fields_save( $post_id ){

$woocommerce_select = $_POST['_my_custom_field'];

if( !empty( $woocommerce_select ) ) {
       update_post_meta( $post_id, '_my_custom_field', esc_attr( $woocommerce_select ) );
       update_post_meta( $post_id, '_stock_status', 'outofstock' );
}

}
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save', 999 ); 

I also tried it with a lower or no priority.

This is how I create the custom field:

function woo_add_custom_general_fields() {

global $woocommerce, $post; ?>

<div class="options_group">
        <p class="form-field custom_stock">
            <label for="custom_stock"><?php echo __( 'Custom Stock', 'aat-net-theme' ); ?></label>
            <span class="wrap">
                <?php $custom_stock = get_post_meta( $post->ID, '_my_custom_field', true ); ?>  
                <select id="custom_stock" name="_my_custom_field">
                    <option value="" <?php selected( $custom_stock, '' ); ?>> - Select Stock - </option>
                    <option value="new" <?php selected( $custom_stock, 'new' ); ?>>New</option>
                    <option value="in_stock" <?php selected( $custom_stock, 'in_stock' ); ?>>In Stock</option>
                    <option value="on_request" <?php selected( $custom_stock, 'on_request' ); ?>>On Request</option>
                    <option value="in_transit" <?php selected( $custom_stock, 'in_transit' ); ?>>In Transit</option>
                    <option value="not_available" <?php selected( $custom_stock, 'not_available' ); ?>>Not Available</option>
                </select> 
            </span>
            <span class="description"><?php _e( 'Select the custom stock-status here.', 'aat-net-theme' ); ?></span>
        </p>

<?php }
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
1

There are 1 answers

0
LWS-Mo On

maybe this will be helpfull for somebody else.

I tried many different things, at some point I deactivated my meta-box save function and the fields would still save without a problem.

It seems that my problem was caused by using the 2 default WooCommerce actions to create and save my fields / meta-box.

add_action( 'woocommerce_process_product_meta'...

and

add_action( 'woocommerce_product_options_general_product_data'...

Since I couldnt find a solution I now created a normal WordPress meta-box like this:

function lwsaat_custom_meta() {
    add_meta_box( 
        'lwsaat_meta', // HTML 'id' attribute of the edit screen section
        __( 'Heading', 'lwsaat-plugin' ), // Title of the edit screen section
        'lwsaat_meta_callback', // Function that prints out the HTML for the edit screen section
        'product', // The type of writing screen on which to show the edit screen section
        'normal', // The part of the page where the edit screen section should be shown ('normal', 'advanced', or 'side')
        'high' // The priority within the context where the boxes should show ('high', 'core', 'default' or 'low')
    );
}
add_action( 'add_meta_boxes', 'lwsaat_custom_meta' );

I than created the callback function like so:

function lwsaat_meta_callback( $post ) {

    wp_nonce_field( basename( __FILE__ ), 'lwsaat_nonce' );
    $lwsaat_stored_meta = get_post_meta( $post->ID );
    ?>

        <p class="form-field custom_stock">
            <label for="custom_stock"><?php echo __( 'Custom Stock', 'lwsaat-plugin' ); ?></label>
                <?php $custom_stock = $lwsaat_stored_meta['_aat_stock_select'][0]; ?>   
                <select id="custom_stock" name="_aat_stock_select">
                    <option value="new" <?php selected( $custom_stock, 'new' ); ?>>New</option>
                    <option value="in_stock" <?php selected( $custom_stock, 'in_stock' ); ?>>In Stock</option>
                    <option value="not_available" <?php selected( $custom_stock, 'not_available' ); ?>>Not Available</option>
                    <option value="eu_no_import" <?php selected( $custom_stock, 'eu_no_import' ); ?>>Import to EU not allowed</option>
                </select> 
        </p>
    <?php
}

And the save function like this:

function lwsaat_meta_save( $post_id ) {

    // Checks save status
    $is_autosave = wp_is_post_autosave( $post_id );
    $is_revision = wp_is_post_revision( $post_id );
    $is_valid_nonce = ( isset( $_POST[ 'lwsaat_nonce' ] ) && wp_verify_nonce( $_POST[ 'lwsaat_nonce' ], basename( __FILE__ ) ) ) ? 'true' : 'false';

    // Exits script depending on save status
    if ( $is_autosave || $is_revision || !$is_valid_nonce ) {
        return;
    }


    // Save custom stock select
    $custom_stock = $_POST[ '_aat_stock_select' ];

    if( $custom_stock == 'new' ) {

        update_post_meta( $post_id, '_aat_stock_select', $_POST[ '_aat_stock_select' ] );
        update_post_meta( $post_id, '_stock_status', 'instock' );

    } elseif ( $custom_stock == 'not_available' ) {

        update_post_meta( $post_id, '_aat_stock_select', $_POST[ '_aat_stock_select' ] );
        update_post_meta( $post_id, '_stock_status', 'outofstock' );

    } else {
        update_post_meta( $post_id, '_aat_stock_select', $_POST[ '_aat_stock_select' ] );
    }
}
add_action( 'save_post', 'lwsaat_meta_save' );

With this code I can resave the product stock along with my custom field. It was not possible for me with the native WooCoommerce functions.