WP_query on two custom fields

I need to do a WP_query on two values. Here's the scenario. I have a custom post type "asset_sales" and they have custom fields of "sale_end_date" and "asset_homepage_priority". I need the query to show items in a list ONLY if the "sale end date" has not come and gone. AND I need to sort that list by the Priority number it's given. So basically it would be "Show me all of the sales that haven't expired, but sort them by their priority number in descending order". This is the code I've started with:

$args = array (
'post_type'              => 'asset_sales', // your event post type slug
'post_status'            => 'publish', // only show published events
'meta_key'               => 'asset_homepage_priority', // your ACF Date & Time Picker field
'meta_value' => ' ',
'meta_compare'           => '!=', // Compare today's date with our event date
'orderby'                => 'meta_value', // order by date
'order'                  => 'DESC', // Show earlier events first
'paged' 								 => $paged,
'posts_per_page'         => 3,
);
 $query = new WP_Query( $args );
 if ( $query->have_posts() ) :
 while ( $query->have_posts() ) : $query->the_post(); // Start loop
$count++; //increment the variable by 1 each time the loop executes
// Your custom loop code here
//echo "sale end date: " . get_field('sale_end_date') . " | current date: " . $todaysdate . "<br>";
$image = Bunyad::core()->get_sidebar() == 'none' ?  'main-featured' : 'main-block';
$saledateraw = get_field('sale_end_date');
$saleenddate = date("F j, Y", strtotime($saledateraw));
$prioritynumber = get_field('asset_homepage_priority');
?>
<?php if ($count < 4) { ?>
<ul class="block posts-list thumb">
<div class="highlights">
<article style="">
<div class="cf listing-meta meta above" style="">
<time class="meta-item" style=""><?php the_field('asset_homepage_caption');?><?php echo ' / Priority: ' . $prioritynumber; ?></time></div>
<a href="<?php the_permalink() ?>" class="image-link">
<?php the_post_thumbnail('overlay-large'); ?>
</a>
<div style="width: 100%; height: 110px;"> </div>
<h2 class="post-title" style=""><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<div class="excerpt">
<?php echo Bunyad::posts()->excerpt(null, Bunyad::options()->excerpt_length_highlights, array('add_more' => false)); ?>
</div>
</article>
</div>
</ul>
<?php } ?>
<?php wp_reset_postdata(); ?>
 <?php endwhile; ?>
<?php endif; ?>

Can someone tell me how to add the priority sort to this?

  • Adam Czajczyk

    Hello Dave

    I hope you're well today and thank you for your question!

    I would go for a simple main query and an additional filter on "posts_where". This query argument set should return all the "asset_sales" posts ordered by the "asset_homepage_priority" value in DESC order:

    $args = array (
    	'post_type'              => 'asset_sales', // your event post type slug
    	'post_status'            => 'publish', // only show published events
    	'meta_key'               => 'asset_homepage_priority', // your priority field
    	'orderby'                => 'meta_value', // order by value of asset_homepage_priority field
    	'order'                  => 'DESC', // order in DESC order
    	'paged' 		=> $paged,
    	'posts_per_page'         => 3,
    );

    then you could put a filter on your query to only fetch those posts with "sale_end_date" not expired yet:

    function my_sales_end_where( $where ) {
    	global $wpdb;
    
    	$where .= " AND ID IN (SELECT post_id FROM ($wpdb->postmeta) WHERE (meta_name = 'sale_end_date' AND meta_value < NOW()))";
    
    	return $where;
    
    }
    add_filter( 'posts_where', 'my_sales_end_where' );

    What that does is that it "extends" the default "WHERE" query part to include only those posts that has an ID within results of the following "SELECT" query, which in turn only selects those posts that do have set a meta of "sale_end_date" and its value is "less then now".

    Please note though: this is an example code rather than "end solution" as I don't know what's the format of data in your database (especially the "sale_end_date" value) and I don't have such setup with those posts and exactly the same fields etc to be able to test it.

    It should, however, give you an idea on how to handle that and a starting point for further modifications (if necessary).

    Kind regards,
    Adam

  • Dave

    Adam, thank you so much for this! It got me on the right track. Although I wasn't able to implement the filter (I'm more of a designer than a programer, I know enough to be dangerous). I was able to take the first bit of code and modify it adding another media query. Here's my new code, it works like a charm. Thanks again and have a great holiday!!

    $todaysdate = date("Ymd"); // Get current unix timestamp
    
    $args = array (
    	'post_type'              => 'asset_sales', // your event post type slug
    	'post_status'            => 'publish', // only show published events
    	'meta_key'               => 'asset_homepage_priority', // your priority field
    	'orderby'                => 'meta_value', // order by value of asset_homepage_priority field
    	'order'                  => 'DESC', // order in DESC order
    	'posts_per_page'         => 3,
    	'meta_query' => array(
    		array(
    			'key'     => 'sale_end_date',
    			'value'   => $todaysdate,
    			'compare' => '>=',
    		),
    	),
    );
    
    $query = new WP_Query( $args );

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.