Skip Navigation

[Résolu] Calculating Values based on custom fields

This support ticket is created Il y a 7 années et 2 mois. 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.

Aucun de nos assistants n'est disponible aujourd'hui sur le forum Jeu d'outils. Veuillez créer un ticket, et nous nous le traiterons dès notre prochaine connexion. Merci de votre compréhension.

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)

Ce sujet contient 4 réponses, a 2 voix.

Dernière mise à jour par Christian Cox Il y a 7 années et 2 mois.

Assisté par: Christian Cox.

Auteur
Publications
#570534

Tell us what you are trying to do?

I have created a new custom post type "review" which is a child of the custom post type "business"

The review has a number field called rating, which will hold the star-value (1-5).

The business also has the field called rating. The business rating field should be updated with the average of all the ratings for the reviews for this business. I'd like to hook that into a cron function.

How can I get this done?

#570762

Toolset doesn't offer any easy method for calculating custom field values based on child post custom field values, so this will require a fair amount of custom code. Rather than running this on a CRON, it's probably best to run this whenever a Review is created or modified. If Reviews are added and edited with CRED, you can use the cred_save_data hook. More info about this hook here:
https://toolset.com/documentation/programmer-reference/cred-api/#cred_save_data

To access custom field values in the database, you can use the native WordPress method get_post_meta:
https://developer.wordpress.org/reference/functions/get_post_meta/

Toolset defines parent / child relationships by adding a custom meta key to each child post, "_wpcf_belongs_slug_id", where "slug" is the slug of the parent post type, and the value is the parent post ID. For example, if the parent post type slug is "parent-slug" then the meta key will be "_wpcf_belongs_parent-slug_id". So you will again use get_post_meta to find all child posts associated with a specific parent. Calculate the average value of their ratings (get_post_meta), and set that value in the parent post using update_post_meta:
https://codex.wordpress.org/Function_Reference/update_post_meta

Let me know if you have specific questions about any of these steps and we can discuss in more detail.

#570765

I would prefer to use cron, in order to reduce the stress on the database.

Can you give me an example of getting the value of a field? and setting it?

Thank you

#570772

Ok, so I came up with this basic frame.

What do you think?

register_activation_hook(__FILE__, 'my_activation');

function my_activation() {
    if (! wp_next_scheduled ( 'my_hourly_event' )) {
	wp_schedule_event(time(), 'hourly', 'my_hourly_event');
    }
}

add_action('my_hourly_event', 'do_this_hourly');

function do_this_hourly() {
	
	//Get all Posts of the Type Condo
	// This part may not make sense. 
	
	$condoargs = array(
        'post_type' => 'condo',
        'numberposts' => -1,
        'meta_key' => 'wpcf-' . $numeric_field,
        'meta_query' => array(array('key' => '_wpcf_belongs_' . 'condo' . '_id', 'value' => $parent_id))
    );
    $condo_posts = get_posts($condoargs);
    
    foreach ($condo_posts as $condo_post) {
	
		//	Get the child posts (reviews) for each condo
		
	    $child_posts = array(
        	'post_type' => 'review',
			'numberposts' => -1,
			'meta_key' => 'wpcf-overall-rating',
			'meta_query' => array(array('key' => '_wpcf_belongs_' . 'condo' . '_id', 'value' => $parent_id))
		);
		
		//calculate the overall rating
		
		$overall_rating_i = 0;
		$overall_rating_sum = 0;
		
		foreach ($child_posts as $child_post) {
			
			$overall_rating_sum += get_post_meta( $child_post->ID, 'wpcf-' . 'wpcf-overall-rating' , true );
			$overall_rating_i++;
		
		}
		
		$overall_rating_ave = $overall_rating_sum / $overall_rating_i;
		
		// Set Parent Post's wpcf-overall-rating to $overall_rating_ave
	    
	}
	
}


register_deactivation_hook(__FILE__, 'my_deactivation');

function my_deactivation() {
	wp_clear_scheduled_hook('my_hourly_event');
}

I just need help with: getting all the parent posts. I'm afraid the function I used is not quite there. and for each parent post, I need to set the value of the field wpcf-overall-rating.

#570827

If this is the actual code, you should see errors generated when the cron runs. Go in your wp-config.php file and look for define(‘WP_DEBUG’, false). Change it to:

define('WP_DEBUG', true);

Then add these lines, just before it says 'stop editing here':

ini_set('log_errors',TRUE);
ini_set('error_reporting', E_ALL);
ini_set('error_log', dirname(__FILE__) . '/error_log.txt');

Look here:

$condoargs = array(
        'post_type' => 'condo',
        'numberposts' => -1,
        'meta_key' => 'wpcf-' . $numeric_field,
        'meta_query' => array(array('key' => '_wpcf_belongs_' . 'condo' . '_id', 'value' => $parent_id))
    );
    $condo_posts = get_posts($condoargs);

You'll probably see several errors appear in the logs, because the variables $numeric_field and $parent_id are undefined. I'm not sure what you're trying to accomplish with these variables, so I'm not able to offer much assistance here. If you want to get all condo posts, the args could be much simpler:

$condoargs = array(
  'post_type' => 'condo',
  'numberposts' => -1,
  'post_status' => 'publish'
);
$condo_posts = get_posts($condoargs);
error_log(print_r($condo_posts, true));

Now you should see an array of condo posts written to the log when the cron runs.

Check this slug. You most likely don't need to duplicate the wpcf- prefix like this:

get_post_meta( $child_post->ID, 'wpcf-' . 'wpcf-overall-rating' , true );

To update a custom meta field use update_post_meta:

update_post_meta( $post_id, $meta_key, $meta_value );

Reference:
https://codex.wordpress.org/Function_Reference/update_post_meta