Skip Navigation

[Resolved] Reputation system – calculate average custom field value in related posts

This thread is resolved. Here is a description of the problem and solution.

Problem: I have a many-to-many relationship between two custom post types. In a two-column table View, I want to display the title of each post from post type A in the left column. In the right column, I want to display the average value of a custom field in all the related Type B posts.

Solution: There's nothing exactly like this built into the system, so it's probably best to create a custom shortcode that can be used to query related posts and calculate the average custom field value. See examples below.

Relevant Documentation:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts
https://developer.wordpress.org/reference/functions/get_post_meta/

This support ticket is created 4 years ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 4 replies, has 2 voices.

Last updated by jorgeB-3 4 years ago.

Assisted by: Christian Cox.

Author
Posts
#2114159

Hi,

I'm trying to build a reputation system por companies.

I have two custom post types: Companies and Reputation.

Companies have standard WordPress fields (Company Name -> Post Title, Logo -> Featured Image).

Reputation has a standard WordPress field (Date/Time -> Title) and a Custom Field (Value (numeric)).

Both have a relationship many to many, so many Companies have many reputation Values.

Then I need to show a table with two columns, the first will show the Company Name and the second will show the sum of all the Values divided by the number of Reputation posts belonging to the parent (Company) post.

Does anybody how to do it?

Thank you very much.

Jorge

#2114363

Hello, this sounds like a good candidate for a custom code solution. Toolset does not provide a built-in feature exactly like the calculation you have described. There are some examples here in the forums showing how you can use a custom shortcode system to calculate the sum total of custom field values using a View's loop, but since you also need to divide that total by the number of results to generate an average, it's not a complete solution for you.

If I were going to set up something like this I would start out by creating a custom shortcode that accepts a Company ID as an argument and returns an average Reputation field value. Next, I would create a View of Company posts. In the loop I would set up a table display with two columns. In the first column, I would display the post title or post link. In the second column, I would insert my custom shortcode.

If you're interested in exploring the custom code approach, let me know and I can work on some examples for you. I can show you some general templates for creating custom shortcodes, and other examples using our PHP APIs to query related posts and calculate values using their custom field values.

#2114511

Hi Christian,

Thank you for your reply and explanations.

Yes I would like to know more about the custom code and examples.

Best regards.

#2114787

Okay sure, here are some examples. The first snippet is a PHP snippet that creates a custom shortcode that will add up the custom field values from related posts and return an average:

// shortcode that takes a company ID, gets the related reputation posts, and returns the average reputation value
// https://toolset.com/forums/topic/reputation-system/
add_shortcode( 'avg-company-rep', 'tssupp_avg_company_rep');
function tssupp_avg_company_rep($atts)
{
  $relslug = 'your-relationship-slug';
  $fieldslug = 'your-value-field-slug';
  $decimal_places = 4;

  // probably should not edit below this line

  $a = shortcode_atts( array(
    'companyid' => 0,
  ), $atts );
  if($a['companyid'] == 0)
    return;
  $total_rep = 0;
  $reps = toolset_get_related_posts(
    $a['companyid'],
    $relslug,
    [
      'query_by_role'   => 'parent',
      'limit'           => 1000,
      'offset'          => 0,
      'args'            => [],
      'role_to_return'  => 'child',
    ],
  );
  // if there are no related reputation posts, return reputation of '0'
  $num_reps = count($reps);
  if($num_reps == 0)
    return 0;
  
  // return the average of all reputation values
  foreach($reps as $rep) {
    $total_rep+= intval(get_post_meta($rep, 'wpcf-'.$fieldslug, true));
  }
  $avg = round($total_rep/$num_reps, $decimal_places);
  return $avg;
}

You should replace your-relationship-slug with the slug of the M2M relationship, replace your-value-field-slug with the slug of the numeric reputation field, and replace the 4 in $decimal_places with the number of decimal places you want to display for the average reputation value. You may also need to switch parent and child depending on how your M2M relationship is set up. The code now is written assuming the parent is Company and the child is Reputation. If yours is the opposite, switch the words parent and child in the code. If you are not sure which post type is the parent and which is the child, go to Toolset > Relationships, edit this M2M relationship, and confirm you understand the risk of editing the relationship. Do not make changes here, but you can check which side is the parent and which is the child. It's not always obvious.

Then insert the custom shortcode in the loop of a View of Company posts, like this:

Average reputation: [avg-company-rep companyid="[wpv-post-id]"][/avg-company-rep]
#2115211

My issue is resolved now. Thank you!