web-dev-qa-db-fra.com

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'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();
        }
    }
}
3
Sisir

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';
3
soulseekah

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 ){ ... }
0
Jon Dingman