Brian Johnson Brian Johnson - 1 year ago 38
PHP Question

Filter WordPress Results Based on Calculations for Each

I am running a WordPress query. To determine which posts I want to display, a calculation needs to be run on each post.

To use an example, let's say all of my posts have a custom field, "my_custom_field". The value is an integer between 1 and 100.

The user then inputs a number between 1 and 100 as well. For each post, we subtract the user's number from the value of my_custom_field. It the result is larger than 10, we display that post in our results.

How do I run that query? I can't seem to figure out which direction to go with this.

Keep in mind, this is just a simplified example of a complicated problem. Assume that we are actually going to need to run a calculation for every post. I realize that in this simple example, you could solve the equation and figure out the range of values that you should display. This won't work in my real-world usage.

Here's an example of how I might want to do it. The problem is, of course, that you can't actually run functions and calculations in the $args array. This is merely to demonstrate what I'm trying to accomplish, I understand that this is not how an $args array works.

$args = array ( $a = get_field('my_custom_field'); //I'm using ACF which uses get_field, not important
$b = $user_inputted_field //The value the user entered

Display posts where: $a - $b > 10 //Not real code... Just showing my intention

$the_query = new WP_Query( $args );

// The Loop
if ( $the_query->have_posts() ) {
//Display our posts

I've been able to enable or prevent posts from DISPLAYING by basically putting that code form my $args into the display portion of the loop, but of course that's very sloppy and messes horribly with pagination.

I need some way to run that calculation on each post in the WP_Query object and remove all posts that don't meet those criteria. How can I manually filter those results before I actually run the loop?

Answer Source

Figured it out! Essentially the secret is to run two loops. The first one, instead of displaying the results in the loops, runs a calculation on each result and then depending on the outcome of that calculation, adds the post ID to a string. That string is later used as an argument for the second loop, which displays these hand-picked posts.

So our first loop looks like:

$results = array(); //Set up our array, empty for now
$the_query = new WP_Query( $args );

// The Loop
$posts = $the_query->get_posts();

foreach($posts as $post)  {

$a = get_field('my_custom_field'); //I'm using ACF which uses get_field, not important
$b = $user_inputted_field

if ( $a - $b > 10 ) { 

array_push($results, get_the_ID()); //Add the ID of this post to our array



Then, for the second loop, we just need to set up our $args array to utilize the array of post IDs we have. Also note, that we have to rename the args array and some variables so they don't overlap with our first loop and cause problems.

$args2 = array(
         'post_type' => 'page', //I'm looking for pages, you might not be
         'post__in' => $results

$the_query2 = new WP_Query( $args2 );

// The Loop
if ( $the_query2->have_posts() ) { 
while ( $the_query2->have_posts() ) {
$the_query2->the_post(); ?>

                //Do something. This is where you would DISPLAY the posts

} }
/* Restore original Post Data */

Boom! There it is. It's actually not too difficult, it's just hard to think of this if you've never done it before. I also have a much more in-depth example on my blog. In it, I use a more practical example of what I'm doing here. I perform a [radial search to find locations near the user] It might help explain why you would ever want to do this!