0

I have written a function which hides the product visibility if certain needs are meet, it works if I use the following filter.

add_filter('woocommerce_product_is_visible', 'tm_remove_product_stock_region', 10,2);

The above is ok but when I try to use the following to apply my filter globally when using WP_Query is just won't work.

add_action('pre_get_posts', 'tm_remove_product_stock_region');

I get these two errors "Notice: Undefined variable: product_id", "Warning: Missing argument 2"

I just can't figure out what the issue is.

function tm_remove_product_stock_region($query) {    

    $product_variable = new WC_Product_Variable();
    $product_variations = $product_variable->get_available_variations();

    foreach ( $product_variations as $variation ) {

        /** Get users region. */
        $user_region = tm_get_user_region();

        /** Get products regions. */
        $product_region = $variation['attributes']['attribute_pa_regions'];
        if ( $user_region === $product_region && ! $variation['is_in_stock'] ) {

        /** Show product */
        $meta_query = array(
            'key' => '_visibility',
            'value' => 'visible',
            'compare' => '='
         );

        $query->set('meta_query', $meta_query);

        }
        else if ( $user_region === $product_region && $variation['is_in_stock'] ) {

         /** Hide product */
        $meta_query = array(
            'key' => '_visibility',
            'value' => 'hidden',
            'compare' => '='
         );

        $query->set('meta_query', $meta_query);

        }
    }

   return $query;

}

//Look into apply_filter
add_action('pre_get_posts', 'tm_remove_product_stock_region');
0

That's not really how the pre_get_posts works. The original parameters you've sent to the function are not good.

The only one required is $query.

And the workaround for you will be to run your function in the pre_get_posts function to return an array of post_ID corresponding on the variation you want to include, then in the pre_get_posts function, you will need to $query->set arguments, like this (that's just an example, you've got to find the right ones):

$query->set('post__in', $include_products);
return $query; // at the end of the function

You can read more about the action here

UPDATE About meta_query argument (also tax_query...) : it always has to be an array of array to enable any relation between different meta_key, So, your code need to be,

$query->set('meta_query', array($meta_query) );

Or in a different way embed the array of array directly in $meta_query

$meta_query = array(
    array(
        'key' => '_visibility',
        'value' => 'visible',
        'compare' => '='
     )
);

UPDATE 2

You can try to make it easier, using the WP_Query post__in parameter, but I don't know if it will work as it will depends on the extra woocommerce filter and action to hide product, in that case you might try different priority for the pre_get_posts action :

function tm_remove_product_stock_region($query) {

$product_variable = new WC_Product_Variable();
$product_variations = $product_variable->get_available_variations();

// you don't need to run the function in the loop, the user_region is always the same
/** Get users region. */
$user_region = tm_get_user_region();

$post__in = array();

foreach ( $product_variations as $variation ) {

    /** Get products regions. */
    $product_region = $variation['attributes']['attribute_pa_regions'];

    if ( $user_region === $product_region && ! $variation['is_in_stock'] ) {

        $post__in[] = $variation['product_id'];

    }
    else if ( $user_region === $product_region && $variation['is_in_stock'] ) {

        $post__in[] = $variation['product_id'];

    }

}
if(is_array($post__in) && $post__in != null){
    $query->set('post__in', $post__in);
}
return $query;

}

//Look into apply_filter
add_action('pre_get_posts', 'tm_remove_product_stock_region');

Hope it helps !

| improve this answer | |
  • I tried this $meta_query = array( 'key' => '_visibility', 'value' => 'visible', 'compare' => '=' ); //$is_visible = false; $query->set('meta_query', $meta_query); but still no joy – Chuck Norris May 26 '17 at 14:29
  • Can you update your question and add your new function to it, please. – Benoti May 26 '17 at 14:32
  • I've update my answer ;-) Hope it will work ! – Benoti May 26 '17 at 15:01
  • I tried adding the second array to meta_query but the filter is still returning every product, including the ones that are meant to be hidden. Also now it's giving me a notice/warning that says Undefined variable: meta_query. – Chuck Norris May 26 '17 at 15:46
  • You certainly need to extract the $meta query and $query->set from the foreach loop, because you override $meta_query each time the foreach loop. And there is no relation between visible and hidden array. And the undefined is maybe du to the fact that you don't have else clause. – Benoti May 26 '17 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.