Here is another approach with pre_get_posts
.
Use get_posts()
( x2 queries ) to get all the post ids of each post type according to its requirements. Add the fields
parameter ('fields' => 'ids'
) to your query arguments to just fetch post ids as this is what we need, nothing else. This will drastically improve performance and will not be that tough on resources. So, you will end up with two arrays of post ids
You now need to merge the two arrays with array_merge()
to create a "super" array which will hold all the post ids
You would want to look into saving this in a transient and flushing the transient when a post is updated, trashed, untrashed or published. This will ensure that do not comprise performance of your site.
Now that you have an array of ID's fitting your needs, you can just pass that array of post ids to post__in
in pre_get_posts
Example (and untested as this is only an illustration. Unfortunately I don't have time for proper coding)
function get_all_special_posts()
{
/*
* This is here were you would want to introduce your transient
*/
$args1 = [
'post_type' => 'post_type_1',
'fields' => 'ids',
'nopaging' => true,
'meta_query' => [[ /*Your specific custom fields */ ]]
];
$query1 = get_posts( $args1 );
$args2 = [
'post_type' => 'post_type_2',
'fields' => 'ids',
'nopaging' => true,
'meta_query' => [[ /*Your specific custom fields */ ]]
];
$query2 = get_posts( $args2 );
$post_ids = array_merge( $query1, $query2 );
/*
* Set your transient here, you would want to store $post_ids in the transient
*/
return $post_ids;
}
Remember to create a function to flush your transient on post publish, trash, untrash and update. Look at transition_post_status
for this. Very versatile hook. Use $post->post_type
to target your two desired post types only
add_action( 'pre_get_posts', function ( $q )
{
if ( !is_admin() && $q->is_main_query() && $q->is_home() ) {
$q->set( 'post__in', get_all_special_posts() );
}
});
Just to note, I would first check whether get_all_special_posts()
actually have a valid array and that it is not empty before passing it to post__in
posts_where
. One of the two should do it. I love a goodWP_Query
question, but don't have time to write an answer. Do you have the exact SQL you need to query to generate?