Ask your WordPress questions! Pay money and get answers fast! (more info)

Calculating custom value + sorting by rank

Hello all,

I recently received some great help from Andrea P. here @ WPQuestions with regards to building a trip logger and tracker. I've run into one final issue that I'm trying to navigate my way through. Essentially, what is being built is a leaderboard/tracker, where trips are submitted as a custom post type. There is a also a post type for companies, where employee counts are saved as ACF meta. The leaderboard itself should rank companies by the total number of trips per capita (# of trips for each company/# of company employees). This is all hooked together, but the order is not right.

The screenshot shows that if I echo $per_capita_val just to see what's there, i get these numbers -- which is clearly what its sorting by -- but obviously isn't the correct value. Vital design, for example, has 25 employees, which would put their per capita at 2.44.

<strong>Main Template:</strong>

// get all terms of the companies taxonomy
$companies = get_terms('companies_tax');

// loop them and create a new array with $term_id => $per_capita_trips
$companies_array = array();
foreach ($companies as $company){
// calculate the per-capita
$per_capita_trips = calculate_per_capita_trips( intval($company->term_id), $company->count );
// if we've got a value, add it to the array
if ($per_capita_trips){
$companies_array[$company->term_id] = $per_capita_trips;

// order the list based on the per-capita

// now we can loop each term (company) and retrieve all posts (trips) from that company
// you could set up a counter variable to print the position (like in your mockup)

//set a counter for the rank position
$company_rank = "1";

// example loop
foreach ( $companies_array as $company_id => $per_capita_val){
// query all the trips whithin this company term
$company_args = array(
'post_type' => 'trips',
'posts_per_page' => -1,
'tax_query' => array(
'taxonomy' => 'companies_tax',
'field' => 'id',
'terms' => $company_id,
'operator' => 'IN',
'include_children' => false

$company_trips = new WP_Query( $company_args );
// loop the trips from this company
if ( $company_trips->have_posts() ) :

echo '<div class="cotable">';
echo '<div class="corow">';

// print company header
echo '<div class="cells rankblock"><div class="ranked color' . $company_rank . '">'.$company_rank.'</div></div>';
// get company term, so we can print out the heading for the company
$company_obj = get_term( $company_id, 'companies_tax' );
//print name (taken from taxonomy)
echo '<div class="cells coname"><h3 class="open' . $company_rank . '">'.$company_obj->name.'</h3></div>';
// number of trips
echo '<div class="cells triptotal">'.$company_obj->count.'</div>';

$post_ids = wp_list_pluck( $GLOBALS['company_trips']->posts, 'ID' );
$idList = implode(",", $post_ids); //turn the array into a comma delimited list
$meta_key = 'miles';//set this to your custom field meta key
$allmiles = $wpdb->get_var($wpdb->prepare("
SELECT round(sum(meta_value), 2)
FROM $wpdb->postmeta
WHERE meta_key = %s
AND post_id in (" . $idList . ")", $meta_key));
echo '<div class="cells totalmiles">' . $allmiles . '</div>';
echo '<div style="display:none;">';
echo $per_capita_trips;
echo '</div>';
echo '</div>';
echo '</div>';
echo '<div class="hiddenblock block' . $company_rank . '">';
echo '<div class="parttable">';
echo '<div class="partrow topbar"><div class="cell">Name</div><div class="cell">Date</div><div class="cell">Mode</div><div class="cell">Miles</div></div>';

// this loop all trips posts from this company term
// you can print out whatever you want from each trip post, like in a normal loop
while ( $company_trips->have_posts() ) : $company_trips->the_post(); ?>

<div class="partrow">
<div class="cell"><?php the_author_meta('first_name'); ?></div>
<div class="cell"><?php if(get_field('tripdate')) { ?><?php the_field('tripdate'); ?><?php } else { ?>--<?php } ?></div>
<div class="cell"><?php the_field('mode'); ?></div>
<div class="cell"><?php the_field('miles'); ?></div>

<?php endwhile; echo '</div></div>'; endif; wp_reset_postdata(); $company_rank++; } ?>

<strong>Functions file:</strong>

// define the function to calculate the per capita value
// assuming that companies details are stored in custom posts of the post_type 'companies'
// which have an ACF taxonomy field called "company_term_id" which uses a single selector and pass the term_ID from the taxonomy "companies_tax"
// and also have a normal field called "company_employees" where you store the number of employees

function calculate_per_capita_trips( $term_id, $trips_count ){
// query the companies to retrieve the company page id
$args = array(
'post_type' => 'companies',
'posts_per_page' => 1,
'fields' => 'ids',
'meta_key' => 'company_term_id',
'meta_value_num' => $term_id,
'meta_compare' => '='

$companies_query = new WP_Query( $args );
// loop it (we are getting just an array of ids, as we don't need anything else from that post now
if ($companies_query->have_posts()):
foreach( $companies_query->posts as $company_id ):
// get the number of employees
$employees = get_field('company_employees', $company_id);
// calculate the per-capita
$per_capita = $trips_count / $employees;
//echo '<br/>'.$per_capita;
// if we've got the value return it, otherwise return false
if ($per_capita){
return $per_capita;
return false;

Answers (1)


Bob answers:

The issue is with this loop in your function

if ($companies_query->have_posts()):

foreach( $companies_query->posts as $company_id ):

// get the number of employees

$employees = get_field('company_employees', $company_id);

// calculate the per-capita

$per_capita = $trips_count / $employees;

//echo '<br/>'.$per_capita;



you are overriding $per_capita variable or wordpress query is not proper. The $trip_count is different but the employees are same always. Means the last company employee. It is 15.

60/15 = 4.0666666666667
49/15= 3.2666666666667
40/15= 2.6666666666667
36/15 = 2.4
35/15 = 2.3333333333333

Bob comments:

I am not 100% sure about your setup of custom taxonomy and custom post type.

can you check which value do you get in <strong>$companies_query</strong> in your function?