Tell us what you are trying to do?
I have 2 custom fields called 'Rating' and 'Count' in a custom field group. I assigned that custom field group to a Custom post type.
Now when ever I create a Post, I provide a value to the custom field Rating and I set the value of Count to 1.
Now I created a form with which people can submit their Ratings. And I want to store the average value of all the ratings provided by the users in the Rating custom field. So whenever someone will submit their rating I want to perform 2 actions 'Rating = (Rating * Count + New Rating Value Given By User)/(Count+1)' and 'Count = Count + 1'
How can I achieve it?
I need a few clarifications before being able to answer the question:
1. What is the name of the post type?
2. Do you add many posts inside that post type?
3. If yes, do you manually as an admin add a value in the rating field and 1 in the count field for each post?
4. Which form now do you want to create? To create a post of that post type or to edit one of the posts in the post type?
Now to store the average of the ratings as it should read all the rating entries in the single post items it means there is one average rating option for the whole website.
If that is the case you will need to create a new post type called global options, and add the custom field of `Average Rating` there.
Then on each form submission of the other post type you will need to use the hook below:
https://toolset.com/documentation/programmer-reference/cred-api/#cred_save_data
On that hook you will get the value that the user adds and do the calculation and add it to the global option Average Rating field.
But before going for the details, you will need to answer my questions to see if I understood the issue correctly or not.
1. What is the name of the post type?
The name of the post type is 'SAAS' and 'Text To Speech'
2. Do you add many posts inside that post type?
Yes, there will be numerous posts inside each post type.
3. If yes, do you manually as an admin add a value in the rating field and 1 in the count field for each post?
Yes, I manually as an admin add a value in the rating field and 1 in the count field for each post.
4. Which form now do you want to create? To create a post of that post type or to edit one of the posts in the post type?
I want to edit one of the posts in the post type.
5. Now to store the average of the ratings as it should read all the rating entries in the single post items it means there is one average rating option for the whole website.
Ans: Each post will have its own average rating value which will be of all the inputs that the users will provide. A user can provide only one rating value at a time for each post.
Hi there,
Thank you. I have the code below that can be considered as the starting point to check further and fine tune it for your usecase:
add_action( 'cred_save_data', 'update_rating_and_count', 10, 2 );
function update_rating_and_count( $form_data, $post_id ) {
// Check if this is the correct form ID
if ( $form_data['id'] == 123 ) { // Replace 123 with your Toolset form ID
$rating = (float) get_post_meta( $post_id, 'rating', true );
$count = (int) get_post_meta( $post_id, 'count', true );
$new_rating = (float) $_POST['cred_form_data']['fields']['rating'];
$new_rating_value = ($rating * $count + $new_rating) / ($count + 1);
update_post_meta( $post_id, 'rating', $new_rating_value );
$new_count = $count + 1;
update_post_meta( $post_id, 'count', $new_count );
}
}
Note: This code assumes that the rating and count fields are Toolset custom fields, and that the Toolset form ID for the post edit form is 123. You'll need to adjust these values in the code to match your specific setup.
See if it works for you.
Thanks.
The code isn't working. Can you kindly check?
You can test it on my test site: hidden link
Hi there,
I can try to see what is the issue. I'd appreciate it if you could give me the URL/User/Pass of your WordPress dashboard after you make sure that you have a backup of your website.
It is absolutely important that you give us a guarantee that you have a backup so if something happens you will have a point of restore.
Make sure you set the next reply as private.
Hi there,
I changed the code to:
add_action( 'cred_save_data', 'update_rating_and_count', 10, 2 );
function update_rating_and_count( $post_id, $form_data ) {
// Check if this is the correct form ID
if ( $form_data['id'] == 600 ) { // Replace 123 with your Toolset form ID
$rating = (float) get_post_meta( $post_id, 'wpcf-rating', true );
$count = (int) get_post_meta( $post_id, 'wpcf-count', true );
$new_rating = (float) $_POST['cred_form_data']['fields']['rating'];
$new_rating_value = ($rating * $count + $new_rating) / ($count + 1);
update_post_meta( $post_id, 'wpcf-rating', $new_rating_value );
$new_count = $count + 1;
update_post_meta( $post_id, 'wpcf-count', $new_count );
}
}
I changed a few things:
1- I added the function parameters reversed, so the correct function parameters are: function update_rating_and_count( $post_id, $form_data )
2- When using WordPress native post_meta functions, we need to add wpcf- prefix to the name of the Toolser custom fields.
Now the result is as desired.
Thanks.
The code is working but the average value isn't correct. Can you kindly check?
Hi there,
Please check if this part of the code complies with the formula that you have in mind.
$new_rating_value = ($rating * $count + $new_rating) / ($count + 1);
Also, please go to the single post and set 0 for the rating and 0 for the count, and save the page to start over.
FInally, please consider that in the formula section below:
($rating * $count + $new_rating)
First the Multiplying occurs and then the addition. I you want the other way around please indicate it with parentheses.
Thanks.
According to programmer reference, 'cred_save_data' works after saving the form data to the database. So first the form value is getting saved to the database rating column and then the operation is being performed.
Let,
rating = 5;
count=6;
form-value-by-user=3;
Database Update -> rating = 3; //'cred_save_data' Hook works after saving the form data to the database
cred_save_data Hook operation:
$rating = 3 //From database
$count = 6 //From database
$new_rating = 0; // This line ($new_rating = (float) $_POST['cred_form_data']['fields']['rating'];) isn't working. That's why $new_rating = 0
$new-rating-value = (3*6 + 0)/(6+1) = 2.57;
Database Update -> rating = 2.57;
$new-count = 6+1 = 7;
Database Update -> count = 7;
You can check the output 2.57 by providing form-value-by-user = 3 in this page: hidden link
Hi there,
You can use the same logic using the cred_before_save_data hook to avoid that issue.
Here are the details:
https://toolset.com/documentation/programmer-reference/cred-api/#cred_before_save_data
See if that works for you.
Thanks.
cred_before_save_data hook doesn't have the argument $post_id. That's why the code isn't working with cred_before_save_data hook . Can you kindly check?
I edited the code like this.
add_action( 'cred_before_save_data', 'update_rating_and_count', 10, 2 );
function update_rating_and_count( $form_data ) {
// Check if this is the correct form ID
if ( $form_data['id'] == 600 ) { // Replace 123 with your Toolset form ID
$post_id = get_the_ID();
$rating = (float) get_post_meta( $post_id, 'wpcf-rating', true );
$count = (int) get_post_meta( $post_id, 'wpcf-count', true );
$new_rating = (float) $_POST['wpcf-rating'];
$new_rating_value = ($rating * $count + $new_rating) / ($count + 1);
$_POST['wpcf-rating'] = $new_rating_value;
$new_count = $count + 1;
update_post_meta( $post_id, 'wpcf-count', $new_count );
}
}
Is it ok?
Hi there,
That is correct the cred_before_save_data does not have the Post ID and the way you went about it will not work.
I changed the code to this on the website:
add_action( 'cred_before_save_data', 'update_rating_and_count', 10, 2 );
function update_rating_and_count( $form_data ) {
// Check if this is the correct form ID
if ( $form_data['id'] == 600 ) {
if ( isset($_POST['_cred_cred_prefix_post_id']) ) {
$post_id = $_POST['_cred_cred_prefix_post_id'];
$rating = (float) get_post_meta( $post_id, 'wpcf-rating', true );
$count = (int) get_post_meta( $post_id, 'wpcf-count', true );
$new_rating = (float) $_POST['wpcf-rating'];
$new_rating_value = ($rating * $count + $new_rating) / ($count + 1);
$_POST['wpcf-rating'] = $new_rating_value;
$new_count = $count + 1;
update_post_meta( $post_id, 'wpcf-count', $new_count );
}
}
}
Added a Test post and it seems to be working correctly now.
Thanks.
My issue is resolved now. Thank you!