Ad

Hide The Children Products From Grouped Product On Woocommerce Loops

Having all the single products that are assigned to grouped products available and visible on the archive / category pages is not an ideal solution and I'm wondering how to resolve this.

I know there's a "visibility" option in WooCommerce, but that's even less ideal.

As far as I understand it, WooCommerce now uses meta data for this and not post_parent and because of that, I am asking for help on how to update this query to cover that.

The code from here that I tried and doesn't work anymore:

add_action( 'woocommerce_product_query', 'hide_single_products_assigned_to_grouped_product_from_archive' );
function hide_single_products_assigned_to_grouped_product_from_archive( $q ){
    $q->set( 'post_parent', 0 );
}
Ad

Answer

You cant really target the children products from a grouped product on the product query as the data is stored under _children meta_key on wp_post_meta table as a serialized array.

But what you can do is first to add to all children products from your grouped products a custom field. Then you will be able to use that custom field to change the product query.

The following function will do that job and you will run it only once:

function add_a_custom_field_to_grouped_children_products() {
    // get all grouped products Ids
    $grouped_ids = wc_get_products( array( 'limit' => -1, 'type' => 'grouped', 'return' =>'ids' ) );

    // Loop through grouped products
    foreach( $grouped_ids as $grouped_id ){
        // Get the children products ids
        $children_ids = (array) get_post_meta( $grouped_id, '_children', true );

        // Loop through children product Ids
        foreach( $children_ids as $child_id ) {
            // add a specific custom field to each child with the parent grouped product id
            update_post_meta( $child_id, '_child_of', $grouped_id );
        }
    }
}
add_a_custom_field_to_grouped_children_products(); // Run the function

Code goes in functions.php file of your active child theme (or active theme).

Once saved, browse any page of your web site. Then remove that code and save.


Now all your grouped children products will have a custom field. If you add/create more grouped products, you will need the following function that will add that custom field to the children products:

// Add on the children products from a grouped product a custom field
add_action( 'woocommerce_process_product_meta_grouped', 'wc_action_process_children_product_meta' );
function wc_action_process_children_product_meta( $post_id ) {
    // Get the children products ids
    $children_ids = (array) get_post_meta( $post_id, '_children', true );

    // Loop through children product Ids
    foreach( $children_ids as $child_id ) {
        // add a specific custom field to each child with the parent grouped product id
        update_post_meta( $child_id, '_child_of', $post_id );
    }
}

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


Now to finish, the function that will hide from on all product loops the children products from your grouped products:

add_filter( 'woocommerce_product_query_meta_query', 'hide_children_from_grouped_products' );
function hide_children_from_grouped_products( $meta_query ) {
    if( ! is_admin() ) {
        $meta_query[] = array(
            'key'     => '_child_of',
            'compare' => 'NOT EXISTS'
        );
    }
    return $meta_query;
}

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

Related: Filter products from a specific custom meta data in Woocommerce shop page

Ad
source: stackoverflow.com
Ad