Je suis en train de faire un système de révision où je dois trouver la moyenne de note de mise à jour lorsque:
Voici le code que j'ai écrit:
add_action('edit_comment', 'update_business_rating_avg');
add_action('comment_post', 'update_business_rating_avg');
add_action('comment_unapproved_to_approved', 'update_business_rating_avg');
add_action('comment_approved_to_unapproved', 'update_business_rating_avg');
add_action('comment_spam_to_approved', 'update_business_rating_avg');
add_action('comment_approved_to_spam', 'update_business_rating_avg');
function update_business_rating_avg($comment){
//fb($comment);
$post_id = $comment->comment_post_ID;
$post_type = get_post_type($post_id);
if('business' == $post_type){
//fb($post_type);
$args = array(
'post_id' => $post_id,
'status' => 'approve'
);
$comments = get_comments($args);
$total_ratings = 0;
$avg = 0;
foreach($comments as $comment){
$total_points += get_comment_meta($comment->comment_ID, 'rating', true);
$total_ratings++;
}
if($total_ratings > 0){
$avg = $total_points/$total_ratings;
$avg = (float)$avg;
}
$avg = roundToNearestFraction($avg,0.5);
update_post_meta($post_id, 'avg_rating', $avg);
}
}
Problème:
Il me manque encore quelque chose, car lorsqu'un administrateur publie une critique, la fonction n'est pas déclenchée (son approbation est automatique).
Vérifiez la fonction update_business_rating_avg()
et comment j'utilise get_comment_meta()
à l'intérieur de foreach. Est-ce que la performance tue? Y a-t-il une meilleure manière de faire cela? Des surprises SQL personnalisées?
Appréciez votre aide, merci!
RESOLU: Code final
Merci à @Soulseekah de m'envoyer dans la bonne direction. Voici le code final de la solution si quelqu'un en a besoin à l'avenir. Le code SQL est complexe car je devais rejoindre les deux wp_comments
et wp_commentmeta
pour comparer les commentaires approuvés et les commentaires associés à l’ID de publication en cours.
add_action('edit_comment', 'update_business_rating_avg');
add_action('comment_post', 'update_business_rating_avg');
add_action('comment_unapproved_to_approved', 'update_business_rating_avg');
add_action('comment_approved_to_unapproved', 'update_business_rating_avg');
add_action('comment_spam_to_approved', 'update_business_rating_avg');
add_action('comment_approved_to_spam', 'update_business_rating_avg');
add_action('comment_approved_to_trash', 'update_business_rating_avg');
add_action('comment_trash_to_approved', 'update_business_rating_avg');
function update_business_rating_avg($comment){
if ( !is_object( $comment ) ){
$comment = get_comment( $comment );
}
$post_id = $comment->comment_post_ID;
$post_type = get_post_type($post_id);
if('business' == $post_type){
$avg = 0;
global $wpdb;
$query = "SELECT AVG(meta_value) FROM $wpdb->commentmeta ";
$query .= "INNER JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID " ;
$query .= "WHERE $wpdb->commentmeta.meta_key = 'rating' ";
$query .= "AND $wpdb->comments.comment_approved = 1 ";
$query .= "AND $wpdb->comments.comment_post_ID = '$post_id'";
if( $result = $wpdb->get_var($wpdb->prepare($query)) ){
$avg = roundToNearestFraction($result, 0.5);
update_post_meta($post_id, 'avg_rating', $avg);
}else{
// report error
//$wpdb->print_error();
}
}
}
Le hook comment_post
est appelé avec un $comment_id
comme premier argument. Vous pouvez voir pourquoi votre fonction échoue. Il en va de même pour le crochet edit_comment
.
Ajoutez simplement ce qui suit au début de votre fonction:
if ( !is_object( $comment ) )
$comment = get_comment( $comment );
Utilisez une requête SQL personnalisée pour la récupération des métadonnées de commentaire, car, avec ce que vous avez là, vous finirez par interroger la base de données pour chaque commentaire. De plus, je suggérerais en outre d’utiliser les fonctions intégrées SUM
et AVG
Fonctions MySQL pour éviter les boucles supplémentaires en PHP.
SELECT SUM(`meta_value`), AVG(`meta_value`)
FROM `{$wpdb->commentmeta}`
WHERE `meta_key` = 'rating'
AND `comment_id` = '$sanitized_comment_id';
J'ai trouvé qu'avoir le résultat $ dans l'instruction if () ne fonctionnait pas pour moi.
if( $result = $wpdb->get_var($wpdb->prepare($query)) ){
Donc, si vous avez le même problème, essayez ceci:
$result = $wpdb->get_var($wpdb->prepare($query));
if( $result ){ ... }