This is likely not the “ideal” approach, but this works for me, and now I can move on to other things. If someone has a better option, I’d love to hear it, thank you.
$base_args = [
'post_type' => 'crowdfunding',
'numberposts' => 30,
'posts_per_page' => '50',
];
$meta_query = array(
array(
'key' => 'campaign_start_date',
'compare' => '<=',
'value' => $in_three_days,
),
array(
'key' => 'campaign_end_date',
'compare' => '>=',
'value' => $today,
),
);
$args = array(
'meta_key' => 'campaign_end_date',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => $meta_query,
);
$crowdfunding_posts = new WP_Query(get_posts(array_merge($base_args, $args)));
usort($crowdfunding_posts->query, function($a, $b) {
return strcasecmp(
$b->campaign_is_featured,
$a->campaign_is_featured,
);
});
And now it’s behaving just like I want it to. I can take the little hit for the sort because the page itself is also being cached.