Is this possible via query args?
I don’t think so.
Is this possible via
'posts_where'
?
It is probably doable using some 'posts_*'
filters, not only with 'posts_where'
. Or maybe using 'posts_request'
filter to completely oveeride the query.
Do I need to run a separate query and then somehow merge the results?
That would be the simplest choice, the most easy to customize e.g would be easy to use a limit for products and a different limit for product variations.
Moreover, this approach is not necessarily the worst on performance side, because not always 2 queries are slower than a single one if the latter is very complex.
The 4th alternative would be build a completely custom SQL. A (vaguely tested) query that might do the trick is the following:
$products_and_variations = $wpdb->get_results("
SELECT * FROM (
SELECT products.* FROM {$wpdb->posts} products
LEFT JOIN {$wpdb->postmeta} meta1 ON meta1.post_id = products.ID
LEFT JOIN {$wpdb->postmeta} meta2 ON meta2.post_id = products.ID
WHERE products.post_type="product"
AND products.post_status="publish"
AND (meta1.meta_key = '_visible' AND meta1.meta_value="1")
AND (meta2.meta_key = '_available' AND meta2.meta_value="1")
GROUP BY products.ID
UNION
SELECT variations.* FROM {$wpdb->posts} variations
LEFT JOIN {$wpdb->postmeta} meta3 ON meta3.post_id = variations.ID
WHERE variations.post_type="product_variation"
AND variations.post_status="publish"
AND (meta3.meta_key = '_featured' AND meta3.meta_value="1")
GROUP BY variations.ID
)
posts
ORDER BY post_date DESC
LIMIT 0, 100
");
You can notice:
- how complex it is
- how is not possible to use a limit for products and a different limit for variations: it is only possible to limit the merged results.
Before to use something like that, I would test its performance comparing them with the 2-queries approach and only use the custom query if there is any appreciable performance improvement.