Automatically assign products to a defined product

2019-07-09 23:59发布

问题:

In Woocommerce, I am trying to automatically assign a given product category to products if they have a specific custom field value (Using Advanced custom fields plugin to generate this field).

In my functions.php I have :

function auto_add_category ($product_id = 0) {

    if (!$product_id) return;
    $post_type = get_post_type($post_id);
    if ( "product" != $post_type ) return;

    $field = get_field("city");
    if($field == "Cassis"){
        $terms = get_the_terms( $post->ID, 'product_cat' );
        foreach ($terms as $term) {
            $product_cat_id = $term->term_id;
            if($product_cat_id != 93){
                wp_set_post_terms( $product_id, 93, 'product_cat', true );
            }
            break;
        }
    }
}
add_action('save_post','auto_add_category');

But this doesn't work. Any idea please?

回答1:

For save_post hook there is 3 arguments:

  • $post_id (the post ID),
  • $post (the WP_Post object),
  • $update (whether this is an existing post being updated or not: true or false).

The ACF get_field() function works without any need of specifying the post ID in here.

Also, to make your code more compact, light and efficient, you should use conditional functions has_term() with term_exists() instead of get_the_terms() (+ a foreach loop) that is getting all the existing product categories on your website…

So you should try it this way instead:

// Only on WooCommerce Product edit pages (Admin)
add_action( 'save_post', 'auto_add_product_category', 50, 3 );
function auto_add_product_category( $post_id, $post, $update ) {

    if ( $post->post_type != 'product') return; // Only products

    // 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 ( ! current_user_can( 'edit_product', $post_id ) )
        return $post_id;

    if ( ! ( $post_id && function_exists( 'get_field' ) ) ) 
        return; // Exit if ACF is not enabled (just to be sure)

    if ( 'Cassis' != get_field( 'city' ) )
        return; // Exit if ACF field "city" has 'Cassis' as value

    $term_id = 93; // <== Your targeted product category term ID
    $taxonomy = 'product_cat'; // The taxonomy for Product category

    // If the product has not "93" category id and if "93" category exist
    if ( ! has_term( $term_id, 'product_cat', $post_id ) && term_exists( $term_id, $taxonomy ) )
        wp_set_post_terms( $post_id, $term_id, $taxonomy, true ); // we set this product category
}

Code goes in function.php file of the active child theme (or active theme).

Tested and works. It should works for you too.



回答2:

Seems like you're using ACF?

get_field() requires the post id to be passed to it if not used in the loop, so you should make that line $field = get_field("city",$product_id);.

Also, replace $post->ID with $product_id in get_the_terms()

Hope that helps