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

CPT Based Leaderboard Grouped by Meta Entries WordPress

  • SOLVED

Hello,

I have a unique setup for a loop for a project that I'm trying to work my way through. Basically, here's the situation.

- Registered users are logging 'trips' using a front-end form, which is being saved to a custom post type called 'trips'
- Registered users are also part of a team ('usercompany') defined as a custom field when they register
- There is additional meta information (miles commuted, transportation method, etc) that will be displayed with each post (not a problem)

What makes this unique is the way I ultimately need to display this. Because this is a leaderboard in which they want to rank each <strong>company</strong> based on <strong>per capita trips</strong> (number of trips/number of employees at the company, which is a custom number and not necessarily the same number of people registered), there's a couple things in play here. Ultimately, the output should be something - if even possible.

Show all trip posts, but group them by <strong>Company's</strong> and order them by the number of per capital trips (essentially # of posts in a company group / the custom number I have for each company). Ideally, underneath each company group title would be the actual "posts" (trips) within each grouping.

This is a psuedo-taxonomy term type grouping setup, with the added annoyance of the math company as a way to 'sort' the groups.

Attached a rough visual sample which will hopefully clarify a bit.

Answers (2)

2015-06-01

Andrea P answers:

hi there!

I gave it a go and I made some code which could be what you are looking for.

I assumed you are using ACF to create the fields.
I also assumed, as per your last phrase, that you have a custom taxonomy with companies as terms, and you attach the company term to the trips post, based on the submitter's company.
ultimately, I have assumed (and actually is the thing that makes more sense to do, in my opinion), that you have another post type for companies, where you create a post for each company, with all their details, including the number of employees. (to make my code work, you'll also need to have a ACF taxonomy field in company posts, where you select the company term from the taxonomy.

I have made a separate function to calculate the per_capita, so it's easier to eventually change it if your structure is not like the one described above


// 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' => $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;

endforeach;
endif;
// if we've got the value return it, otherwise return false
if ($per_capita){
return $per_capita;
}
else{
return false;
}
}




// 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( $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
arsort($companies_array);
// 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)
$company_rank = "1";

// example loop
foreach ( $companies_array as $company_id => $per_capita_val){
$company_args = array(
'post_type' => 'trips',
'posts_per_page' => -1,
'tax_query' => array(
'taxonomy' => 'companies_tax',
'field' => 'id',
'terms' => array($company_id),
'operator' => 'IN'
),
);
$company_trips = new WP_Query( $company_args );
// The Loop
if ( $company_trips->have_posts() ) :
echo $company_rank;
// get company term
$company_obj = get_term( $company_id, 'companies_tax' );
//print name
echo $company_obj-name;
// number of trips
echo $company_obj->count;

while ( $company_trips->have_posts() ) : $company_trips->the_post();
// print the post (trip)
endwhile;
endif;
// Reset Post Data
wp_reset_postdata();
// increment the rank value for the next company
$company_rank++;

}


*** UPDATED THE CODE ***
there was a typo and the per_capita function was always outputting "false"


Andrew Clemente comments:

Hi,

This looks fantastic, the only hurdle I'm currently having is getting something to output. Everything should be set up correctly. Your original assumptions about the company taxonomy being attached to each trip was dead on. Here's where things currently stand:

<strong>TRIPS</strong>
- Trips custom post type ('trips')
- companies taxonomy ('companies_tax' .. only attached to this trips CPT)

<strong>Companies</strong> (great suggestion to store all this stuff in here by the way)
- ACF taxonomy field pulling from companies_tax so each CO can be matched to the given taxonomy in trips (using company_term_id)
- Employees number field (using company_employees)
- some additional ACF random company meta data fields for profiles thanks to this suggestion (irrelevant to leaderboard)


I've added one test trip but don't have any output, yet the code makes sense to me and I don't believe I'm missing anything unless I'm overlooking something really obvious. The per capita function was rightfully moved to my theme functions and the rest of the loop in place. I did rename the companies taxonomy (which I previously just had called company) to not interfere with the new co. CPT, but flushed the permalinks in case that was creating an issue as well.

If I throw this on a dev server would you be willing to take a look? It's on a production server at the moment but just behind a login wall.

Thanks!


Andrea P comments:

Hi Andrew!

it seems that now your setup is exactly what my code is expecting.. there could be a typo somewhere though.. or a name has not been updated correctly (like are the post_types named in the code, correctly set to match your structure?)

another thing might be the taxonomy field "company_term_id". my code assumes that is a single selector field, which passes the term ID as output. can you double check if this is the case?

if everything is correct and still not working, then it's probably better if I can have a look at a dev server. just pm me the details.
cheers!


Andrew Clemente comments:

PM sent :)

2015-06-01

Fahad Murtaza answers:

Hi

If I can have access to your server or a full backup of your test dat, I can look into it. Seems interesting and long ago I did something like this for a website [[LINK href="https://beachnboat.com/leaderboard/"]]https://beachnboat.com/leaderboard/[[/LINK]]

Let me know. You can send me access details in a private message.


Andrew Clemente comments:

Hi -- I'll PM you shortly -- just gotta move the data out and make a dev server for you