Home › Forums › Front-end Issues › Count field selection in a WP Query
I’m not sure if it’s possible without having a long lines of code…
I have a CPT called cars and there is a field called price where the admin puts the price of each car.
On the front-end, I have a filter that lists price and I am looking for a query that will count how many times it fits under a price bracket.
For example;
£5000 (2)
£10,000 (15)
This is what I had so far but feel like doing this for each price bracket is stupid and a poor way to do it.
$args = array(
'post_type' => 'cars',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
'post_type' => 'cars',
'post_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'sold',
'value' => array('no'),
'compare' => 'IN',
),
)
)
);
$figure_5000 = new WP_Query(
$args,
array(
'key' => 'price',
'value' => '5000',
'type' => 'numeric',
'compare' => '<=',
)
);
$query = new WP_Query( $figure_5000 );
$figure_5000_total = $query->found_posts;
echo $figure_5000_total;
Any ideas, please?
I would create a custom taxonomy. The terms in the taxonomy would be the price brackets. Then I would create an acf/save_post filter. In this filter I would get the price entered, figure out what bracket it belongs in and add the correct term to the post. This will allow showing a list of these terms with their counts which is something built into WP. This taxonomy could also be used to easily show a list of items that are in each bracket.
Absolutely no idea if this would work or not:
<?php
$args = array(
'post_type' => 'cars',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
'post_type' => 'cars',
'post_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'sold',
'value' => array('no'),
'compare' => 'IN',
),
)
)
);
$wp_query = new WP_Query($args);
if ($wp_query->have_posts()) :
$get_price = array();
while ($wp_query->have_posts()) : $wp_query->the_post();
$get_price[] = get_field('price');
endwhile;
endif; #endif $wp_query
$filter_price = array_unique($get_price);
if($filter_price):
foreach($filter_price as $price):
$figure = new WP_Query(
$args,
array(
'key' => 'price',
'value' => $price,
'type' => 'numeric',
'compare' => '<=',
)
);
$query = new WP_Query( $figure );
$figure_total = $query->found_posts;
echo $figure_total;
endforeach;
endif; #endif $filter_price
Basically, you loop all the individual prices and put them into an array
Filter the prices to remove duplicates
Then loop the filtered results and pass the value into your query
Your query then returns the count
Not tried the code!
Hi @jarvis,
Thanks for replying, I’ve tried it and it only outputs one in a loop;
2222222222
I know £10,000 has 1 and £5000 should be around 12
Try adding some debugging to the code, see what outputs you get at the various stages:
<?php
$args = array(
'post_type' => 'cars',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
'post_type' => 'cars',
'post_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'sold',
'value' => array('no'),
'compare' => 'IN',
),
)
)
);
$wp_query = new WP_Query($args);
if ($wp_query->have_posts()) :
$get_price = array();
while ($wp_query->have_posts()) : $wp_query->the_post();
$get_price[] = get_field('price');
endwhile;
endif; #endif $wp_query
echo '<pre>';
print_r($get_price);
echo '</pre>';
$filter_price = array_unique($get_price);
echo '<pre>';
print_r($filter_price);
echo '</pre>';
if($filter_price):
foreach($filter_price as $price):
echo '<p>Price: '.$price.'</p>';
$args = array(
'key' => 'price',
'value' => $price,
'type' => 'numeric',
'compare' => '<=',
);
$wp_query = new WP_Query($args);
$figure_total = $wp_query->found_posts;
echo $figure_total;
endforeach;
endif; #endif $filter_price
So first thing is see what the main array gets
Then see what the filtered results returns
When you then loop the filtered array, output the values as a heading
I did just adjust the query in the foreach, as mentioned, I’ve not tested the code, just trying to cobble it together as a starting point.
Hi @jarvis,
No problem, I appreciate the assistance.
This is what it came back with;
Array
(
[0] => 5199
[1] => 6999
[2] => 7499
[3] => 7799
[4] => 9799
[5] => 10399
[6] => 8699
[7] => 6399
[8] => 7999
[9] => 7399
[10] => 4399
[11] => 4699
)
Array
(
[0] => 5199
[1] => 6999
[2] => 7499
[3] => 7799
[4] => 9799
[5] => 10399
[6] => 8699
[7] => 6399
[8] => 7999
[9] => 7399
[10] => 4399
[11] => 4699
)
Price: 5199
2
Price: 6999
2
Price: 7499
2
Price: 7799
2
Price: 9799
2
Price: 10399
2
Price: 8699
2
Price: 6399
2
Price: 7999
2
Price: 7399
2
Price: 4399
2
Price: 4699
2
It’s looping the prices just not the count correctly which is odd.
Ah, think we need one minor amend, please try:
<?php
$args = array(
'post_type' => 'cars',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
'post_type' => 'cars',
'post_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'sold',
'value' => array('no'),
'compare' => 'IN',
),
)
)
);
$wp_query = new WP_Query($args);
if ($wp_query->have_posts()) :
$get_price = array();
while ($wp_query->have_posts()) : $wp_query->the_post();
$get_price[] = get_field('price');
endwhile;
endif; #endif $wp_query
echo '<pre>';
print_r($get_price);
echo '</pre>';
$filter_price = array_unique($get_price);
echo '<pre>';
print_r($filter_price);
echo '</pre>';
if($filter_price):
foreach($filter_price as $price):
echo '<p>Price: '.$price.'</p>';
$args = array(
'key' => 'price',
'value' => $price,
'type' => 'numeric',
'compare' => '<=',
);
$wp_query = new WP_Query($args);
$figure_total = $wp_query->found_posts;
$count = count( $wp_query->get_posts() );
echo '<p>$figure_total: '.$figure_total.' count: '.$count.'</p>';
endforeach;
endif; #endif $filter_price
I think we need count not found
This is what it outputs now @jarvis;
Array
(
[0] => 5199
[1] => 6999
[2] => 7499
[3] => 7799
[4] => 9799
[5] => 10399
[6] => 8699
[7] => 6399
[8] => 7999
[9] => 7399
[10] => 4399
[11] => 4699
)
Array
(
[0] => 5199
[1] => 6999
[2] => 7499
[3] => 7799
[4] => 9799
[5] => 10399
[6] => 8699
[7] => 6399
[8] => 7999
[9] => 7399
[10] => 4399
[11] => 4699
)
Price: 5199
$figure_total: 2 count: 2
Price: 6999
$figure_total: 2 count: 2
Price: 7499
$figure_total: 2 count: 2
Price: 7799
$figure_total: 2 count: 2
Price: 9799
$figure_total: 2 count: 2
Price: 10399
$figure_total: 2 count: 2
Price: 8699
$figure_total: 2 count: 2
Price: 6399
$figure_total: 2 count: 2
Price: 7999
$figure_total: 2 count: 2
Price: 7399
$figure_total: 2 count: 2
Price: 4399
$figure_total: 2 count: 2
Price: 4699
$figure_total: 2 count: 2
Is it because it’s not checking against the figure total? e.g. Cars within £5000 = 5, cars within £7000 = 8
I think it’s the query in the foreach.
What if you change it to:
$args = array(
'posts_per_page' => -1,
'post_type' => 'your post type',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'price',
'value' => $price,
'compare' => '<='
),
)
);
Specify the post type and see if that works?
We know the data up to that point is right, so the issue is that query. Just need to tweak it
Do any of your price ranges only have 2?
If you add a wp_reset_query(); after before the closing for each, does that make a difference?
Hi @jarvis,
Apologies for the delay in getting back to you.
I’ve added the code and this is what was now outputted;
$figure_total: 0 count: 0
Hi @forbiddenchunk,
Please can you post your code? I’d expect at least one value before seeing no results.
Looking at the array, do any of the price ranges only have a total of 2?
Hi @jarvis,
No problem, here is the full code;
$args = array(
'post_type' => 'cars',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
'post_type' => 'cars',
'post_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'sold',
'value' => array('no'),
'compare' => 'IN',
),
)
)
);
$wp_query = new WP_Query($args);
if ($wp_query->have_posts()) :
$get_price = array();
while ($wp_query->have_posts()) : $wp_query->the_post();
$get_price[] = get_field('price');
endwhile;
endif; #endif $wp_query
echo '<pre>';
print_r($get_price);
echo '</pre>';
$filter_price = array_unique($get_price);
echo '<pre>';
print_r($filter_price);
echo '</pre>';
if($filter_price):
foreach($filter_price as $price):
echo '<p>Price: '.$price.'</p>';
$args = array(
'post_type' => 'cars',
'posts_per_page' => -1,
'post_type' => 'your post type',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'price',
'value' => $price,
'compare' => '<='
),
)
);
$wp_query = new WP_Query($args);
$figure_total = $wp_query->found_posts;
$count = count( $wp_query->get_posts() );
echo '<p>$figure_total: '.$figure_total.' count: '.$count.'</p>';
endforeach;
endif; #endif $filter_price
wp_reset_query();
Thanks again for the help in cracking this!
There were 2 errors in the code:
1) The second loop had post_type twice
2) The wp_reset_query was in the wrong place
$args = array(
'post_type' => 'cars',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
'post_type' => 'cars',
'post_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'sold',
'value' => array('no'),
'compare' => 'IN',
),
)
)
);
$wp_query = new WP_Query($args);
if ($wp_query->have_posts()) :
$get_price = array();
while ($wp_query->have_posts()) : $wp_query->the_post();
$get_price[] = get_field('price');
endwhile;
endif; #endif $wp_query
echo '<pre>';
print_r($get_price);
echo '</pre>';
$filter_price = array_unique($get_price);
echo '<pre>';
print_r($filter_price);
echo '</pre>';
if($filter_price):
foreach($filter_price as $price):
echo '<p>Price: '.$price.'</p>';
$args = array(
'post_type' => 'cars',
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'price',
'value' => $price,
'compare' => '<='
),
)
);
$wp_query = new WP_Query($args);
$figure_total = $wp_query->found_posts;
$count = count( $wp_query->get_posts() );
echo '<p>$figure_total: '.$figure_total.' count: '.$count.'</p>';
wp_reset_query();
endforeach;
endif; #endif $filter_price
I’ve tried the above code and it worked for me!
Hi @jarvis,
Thanks, that’s amazing!
Just wondering now in the foreach loop how I add my select fields – for example;
<select name="sort_price" id="sort_price">
<option value="" selected disabled>Select...</option>
<option value="">All</option>
<option value="5000">Up to £5000 (<?php echo $count; ?>)</option>
<option value="6000">Up to £6000 (<?php echo $count; ?>)</option>
<option value="7000">Up to £7000 (<?php echo $count; ?>)</option>
<option value="8000">Up to £8000 (<?php echo $count; ?>)</option>
<option value="9000">Up to £9000 (<?php echo $count; ?>)</option>
<option value="10000">Up to £10,000 (<?php echo $count; ?>)</option>
</select>
What about something like:
<?php
if($filter_price):
echo '<select name="sort_price" id="sort_price">';
echo '<option value="" selected disabled>Select...</option>';
echo '<option value="">All</option>';
foreach($filter_price as $price):
echo '<p>Price: '.$price.'</p>';
$args = array(
'post_type' => 'cars',
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'price',
'value' => $price,
'compare' => '<='
),
)
);
$wp_query = new WP_Query($args);
$figure_total = $wp_query->found_posts;
$count = count( $wp_query->get_posts() );
#echo '<p>$figure_total: '.$figure_total.' count: '.$count.'</p>';
$round_price = round($price, -3);;
echo '<option value="'.$round_price.'">Up to £'.$round_price.' ('.$count.')</option>';
wp_reset_query();
endforeach;
echo '</select>';
endif; #endif $filter_price
Again, untested code so may error or need some tweaking!
Hi @jarvis,
It worked, but not 100% but looking better thanks 🙂
This is the code which I updated slightly;
$args = array(
'post_type' => 'cars',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
'post_type' => 'cars',
'post_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'sold',
'value' => array('no'),
'compare' => 'IN',
),
)
)
);
$wp_query = new WP_Query($args);
if ($wp_query->have_posts()) :
$get_price = array();
while ($wp_query->have_posts()) : $wp_query->the_post();
$get_price[] = get_field('price');
endwhile;
endif; #endif $wp_query
$filter_price = array_unique($get_price);
if($filter_price):
echo '<select name="sort_price" id="sort_price">';
echo '<option value="" selected disabled>Select...</option>';
echo '<option value="">All</option>';
foreach($filter_price as $price):
$args = array(
'post_type' => 'cars',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'price',
'value' => $price,
'compare' => '<='
),
array(
'key' => 'sold',
'value' => array('no'),
'compare' => 'IN',
)
)
);
$wp_query = new WP_Query($args);
$figure_total = $wp_query->found_posts;
$count = count( $wp_query->get_posts() );
$round_price = round($price, -3);;
echo '<option value="'.$round_price.'">Up to £'.$round_price.' ('.$count.')</option>';
wp_reset_query();
endforeach;
echo '</select>';
endif; #endif $filter_price
It outputs the fields but seems to have duplicated them – so the options are;
<option value="5000">Up to £5000 (4)</option>
<option value="7000">Up to £7000 (6)</option>
<option value="7000">Up to £7000 (8)</option>
<option value="8000">Up to £8000 (9)</option>
<option value="10000">Up to £10000 (12)</option>
<option value="10000">Up to £10000 (1)</option>
<option value="9000">Up to £9000 (11)</option>
<option value="6000">Up to £6000 (5)</option>
<option value="8000">Up to £8000 (10)</option>
<option value="7000">Up to £7000 (7)</option>
<option value="4000">Up to £4000 (2)</option>
<option value="5000">Up to £5000 (3)</option>
As you can see it duplicates them and some of the counts aren’t right as
Upto £40000 (0) [cars in that price range]
Upto £50000 (2) [cars in that price range]
Upto £50000 (3) [cars in that price range]
So you know it worked when you output: echo '<p>$figure_total: '.$figure_total.' count: '.$count.'</p>';
That doesn’t duplicate?
So my untested code may just need some refining.
Have a play, perhaps start off by altering the line you know does work, see if you can get it to show both the rounded price and the count, then start adding the other elements
You must be logged in to reply to this topic.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.