Tell us what you are trying to do? Hi, I am trying to create a review system without using other plugins that follow this logic:
1. People leave a review on a child 'recipe-review' type CRED form attached to the parent 'recipe' page. They choose stars 1 - 5 as radio buttons.
2. When they submit, the review is saved (and can be moderated), together with the parent post reference.
3. At the same time, custom number fields on the parent 'recipe' type are calculated and updated - the average rating and the total number of ratings.
4. These values can then be displayed on the page, and used by views to sort results.
For me, the only one not working is number 3. I also have to finish the styling of the stars, but don't think this will be a problem.
It seems like a common requirement and I've followed several threads and tried several solutions but without any success: the code added to my functions.php doesn't update the custom fields. You can see my last attempt here:
Grateful for any help! And I'll happily write up a single post when I get it working.
The reason I want to avoid using other plugins is to reduce bloat and to cut down on upgrade problems. Toolset already had pretty much everything required - just a couple of code snippet and some styling is needed.
Then, regarding #3 - what calculation and fields you would like to update at what point? Can you please share all required information and I will try to guide you in the right direction.
I have set the next reply to private which means only you and I have access to it.
I've added the following code to "Custom Code" section offered by Toolset:
=> hidden link
//*Update Avg Ratings and Total # of Ratings after review submission
function func_update_post_ratings($post_id, $form_data){
// if a specific form, change ID to the CRED "Review" ID
if ($form_data['id']==63) {
//Get ID of Post Being Reviewed
$current_post_id = $form_data["container_id"];
$total_rating = get_post_meta( $current_post_id, 'wpcf-total-ratings',true);
if(empty($total_rating)) {
$total_rating = 1;
$avg = $_POST['wpcf-ratings'];
}else{
$old_total_rating = $total_rating;
$avg = get_post_meta( $current_post_id, 'wpcf-average-rating',true);
$total_rating = $total_rating+1;
$avg = ((($avg*$old_total_rating) + $_POST['wpcf-ratings'])/$total_rating);
}
update_post_meta( $current_post_id, 'wpcf-average-rating', $avg );
update_post_meta( $current_post_id, 'wpcf-total-ratings', $total_rating );
}
}
add_action('cred_save_data', 'func_update_post_ratings',10,3);
I can see rating fields are updated and working as expected.
Thanks for your time! It is looking a lot better thanks to your code snippet. I realised something though: that it makes sense to moderate reviews before they are published. I should have thought about this earlier, sorry.
So I have changed the CRED form to 'pending'. This means that we should change the trigger - so that these fields are not updated when the CRED form is submitted, but are updated when the recipe review is moderated here:
hidden link
So would that be possible? EG When the recipe-review post is changed from pending to published, the fields on the parent post are calculated. And only the published reviews are calculated.
I also noticed that the Total review wasn't calculating quite right. If I delete some reviews, this is not reflected in the review total. The review total seems to +1 without recalculating.
Lastly, it would be great to limit the average field to 1 decimal place - so that 2.8759 > 2.8, and 3 > 3.0. Would this be possible?
So I have changed the CRED form to 'pending'. This means that we should change the trigger - so that these fields are not updated when the CRED form is submitted, but are updated when the recipe review is moderated here:
hidden link
So would that be possible? EG When the recipe-review post is changed from pending to published, the fields on the parent post are calculated. And only the published reviews are calculated.
===>
You can use the post Post_Status_Transitions transition hook and adjust the code accordingly. so, when post status is changed from pending to publish - the same code you should try to run and maybe at some point you need to adjust the code as well.
=> https://codex.wordpress.org/Post_Status_Transitions
I also noticed that the Total review wasn't calculating quite right. If I delete some reviews, this is not reflected in the review total. The review total seems to +1 without recalculating.
===>
You can use the before_delete_post hook and deduct the 1 from review total.
- https://codex.wordpress.org/Plugin_API/Action_Reference/before_delete_post
Lastly, it would be great to limit the average field to 1 decimal place - so that 2.8759 > 2.8, and 3 > 3.0. Would this be possible?
===>
You should use custom shortcode and pass your field value and format the number as required.
So I've been having a go at the three points you suggested, but I didn't have much luck. Reducing the number to one decimal point with a shortcode worked, but I wasn't then able to insert that into a link to substitute with an image.
This was only for the display of the stars though, so I'm sure I can find anther solution. The tricky parts were the points regarding the php - changing the trigger and retrieving the total review count. In reality, the total review count can simply be a count of the number of published reviews (child posts) instead of a calculation.
Anyway, I'm not so versed in php so if you could help with this it'd be much appreciated!
If you want to count the number of child posts based on your relationship, you can use the post-relationship API function: toolset_get_related_posts();
Thanks Minesh, the child posts are being counted so I have my total reviews shortcode. I'm slowly learning!
So really it's just the review calculation now. I don't understand how to make the post transition a trigger. If you could I'd really appreciate some help with that. The logic is this:
In wp-admin, when a recipe-review (child) post status is changed to published, the number rating field from all the child posts (related to that parent post) is added up and divided by the total number of child posts, then written to the Average rating field in the parent 'recipe' type. This should only happen on published child posts - so pending / drafts etc should be ignored. The calculation should be limited to one decimal point. - eg 3.545 becomes 3.5
Many thanks if you get a chance to look at this. Joe
now, above code will only fire when post status is changed from pending to published and at that time all calculations for average rating and total rating will be made.
Hi Minesh, thanks so much for your help! This is now resolved and I'm really please I've finally got it working, so thank you for the excellent support! You did more than was expected and the result works great!
There are a few things I'm going to improve, but that is beyond the scope of this request. I'll finish off the design and write it up as a complete post so that if someone wants to recreate it they'll find it easy.
Where is the best place to write it up? Shall I add it here? I'd also like to add a zip of the 5 star images I created and a few images of the finished design.
All the best and thank again for your time. Much appreciated!! Joe