WP_Query with meta_query for children

Question

I’m using WooCommerce and it has a lot of plugins to handle different stuff.
The one thing needed by the client that no other plugin manages correctly is which variations can be visible for each user role.

So what is happening on the website is that we’re having 6 different roles for registered users and each of them can see only some of the variation of each product.

The following code manages the showing of the variation in the product page and whenever the $product->get_children() method is called.

function vm_woocommerce_get_children($this_children, $instance, $false){
    $user = wp_get_current_user(); // get current user to get its roles
    $logged = is_user_logged_in(); // check whether it's logged
    $hide_for_roles = array(USER_ROLES); // roles that need to be checked
    $to_check = array_intersect($hide_for_roles, $user->roles); // intersection to avoid checking unnecessary roles
    $have_to_hide = count( $to_check )>0 || !is_user_logged_in(); // check if there's actually something to hide
    if($have_to_hide){
        $to_remove = []; // list of indexes to remove
        $k=0;
        foreach($this_children as $variazione){
            // check for each given variation if there's something to hide
            $hide = false;
            // hiding settings are store in the meta of each variation (child of product)
            if($logged) foreach($to_check as $role) $hide |= get_post_meta($variazione, '_'.$role.'_checkbox', true) === "yes";
            else $hide = get_post_meta($variazione, '_guest_checkbox', true) === "yes";
            if($hide) $to_remove[] = $k;
            $k++;
        }
        // remove the given variation
        foreach($to_remove as $rem) unset($this_children[$rem]);
    } // endif have_to_hide
    // set the right variations for the given product
    $instance->set_children($this_children);
    $instance->set_visible_children($this_children);
    return $this_children;
}
add_filter( 'woocommerce_get_children', 'vm_woocommerce_get_children', 10, 3 );

This all works, but whenever I filter the products by the variation attribute, I also see products that have that variation even if that variation is not available for the given product.

To solve this problem I tried the following code:

function vm_pre_filter($query){
    $user = wp_get_current_user();
    $logged = is_user_logged_in();
    $hide_for_roles = array(USER_ROLES);
    $to_check = array_intersect($hide_for_roles, $user->roles);
    $have_to_hide = count( $to_check )>0 || !is_user_logged_in();
    if($have_to_hide){
        $meta_query = $query->get('meta_query');
        if($meta_query=='') $meta_query = [];
        if($logged){
            foreach($to_check as $role)
                $meta_query[] = [ 'key' => '_'.$role.'_checkbox', 'value' => 'yes', 'compare' => '=' ];
        }else{
            $meta_query[] = [ 'key' => '_guest_checkbox', 'value' => 'yes', 'compare' => '=' ];
        }
        $query->set('meta_query', $meta_query);
    }
}
add_action ('pre_get_posts', 'vm_pre_filter');

Which should filter the product based on the said meta values, but the problem is that the query only works for the main products and not the children/variations.

So what I’d need to do is using that meta_query to get the products based on the children meta… is it even possible?

0
ZioCain 3 months 0 Answers 12 views 0

Leave an answer