Exécuter une fonction sur le changement de statut de commentaire
Je suis en train de faire un système de révision où je dois trouver la moyenne de note de mise à jour lorsque:
- Un commentaire est approuvé de en attente/corbeille/spam.
- Un commentaire se lève d'approuver d'approuver
- Un post après commentaires (auto approuvé)
- Un commentaire est édité (à partir d'un tableau de bord personnalisé backend ou frontend lorsque l'utilisateur souhaite éditer/mettre à jour/supprimer sa critique déjà faite)
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'utiliseget_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 ){ ... }