I’m running the following SQL code:
SELECT DISTINCT p.ID
FROM {$wpdb->prefix}posts AS p
INNER JOIN {$wpdb->prefix}term_relationships AS tr ON p.ID = tr.object_id
INNER JOIN {$wpdb->prefix}term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN {$wpdb->prefix}term_relationships AS tr2 ON p.ID = tr2.object_id
INNER JOIN {$wpdb->prefix}term_taxonomy AS tt2 ON tr2.term_taxonomy_id = tt2.term_taxonomy_id
INNER JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND tt.taxonomy = 'product_cat'
AND tt.term_id IN (%s)
AND tt.parent != 0
AND tt2.taxonomy = 'product_visibility'
AND tt2.term_id NOT IN ('" . wc_get_product_visibility_term_ids() . "')
AND pm.meta_key = '_stock_status'
AND pm.meta_value = 'instock'
GROUP BY p.ID
ORDER BY SUM(pm.meta_value) DESC, RAND()
LIMIT %d
Whenever I remove this:
AND tt2.taxonomy = 'product_visibility'
AND tt2.term_id NOT IN ('" . wc_get_product_visibility_term_ids() . "')
Then the code returns products, but with it, it returns nothing (not even visible products). I want to only include products that should be visible on the front end in any way (not private, not password protected, are able to be displayed in search or catalog).
2
Answers
I figured it out. Visible products don't always have a product_visibility entry. Therefore, I had to check if product_visibility was null OR if it did match, whether it was not a product_visibility ID that makes the product invisible. Here is the updated code:
if you are trying to filter the products based on their visibility using
wc_get_product_visibility_term_ids()
, it returns term IDs of the product visibility taxonomies. The problem may be that you are using theNOT IN
which expects a list of values, not a string, so you may need to pass an array of values instead."'"
aroundwc_get_product_visibility_term_ids()
with parentheses()
+ usedimplode()
to convert the returned term IDs array into a comma-separated list of values(should correctly exclude the product visibility terms from the query and only return the visible products)