Запуск функции при изменении статуса комментария
Я создаю систему обзора, в которой мне нужно найти средний рейтинг обновлений, когда:
- Комментарий получает одобрение от ожидающего/мусорного/спама.
- Комментарий получает одобрение от утверждения
- Отзыв о публикации администратора (автоматически одобрен)
- Комментарий редактируется (из пользовательской панели управления бэкенда или интерфейса, когда пользователь хочет отредактировать/обновить/удалить свой уже сделанный отзыв)
Вот код, который у меня есть написанный:
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);
}
}
Проблема:
-
Я все еще чего-то не понимаю, потому что, когда администратор публикует отзыв, функция не запускается (она автоматически утверждается).
-
Проверьте функцию
update_business_rating_avg()
и то, как я используюget_comment_meta()
внутри foreach. Это убивает производительность? Есть ли лучший способ сделать это? Пользовательские параметры SQL?Ценю вашу помощь, спасибо!
РЕШЕНО: Окончательный код
Спасибо @Soulseekah чтобы направить меня в нужное русло. Вот окончательный код решения, если оно кому-то понадобится в будущем. SQL является сложным, потому что мне пришлось присоединиться к wp_comments
и wp_commentmeta
, чтобы сравнить одобренный комментарий и комментарий, связанный с текущим идентификатором записи.
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();
}
}
}
2 answers
В comment_post
крюк вызывается с $comment_id
в качестве первого аргумента.
Вы можете понять, почему ваша функция не работает. То же самое относится и к edit_comment
крюк.
Просто добавьте следующее в начале вашей бизнес-функции:
if ( !is_object( $comment ) )
$comment = get_comment( $comment );
Используйте пользовательский SQL-запрос для извлечения метаданных комментариев, так как прямо сейчас, с тем, что у вас есть, вы в конечном итоге будете запрашивать базу данных для каждого комментария. Более того, я бы дополнительно предложил использовать встроенный SUM
и AVG
Функции MySQL позволяют избежать дополнительных циклов в PHP.
SELECT SUM(`meta_value`), AVG(`meta_value`)
FROM `{$wpdb->commentmeta}`
WHERE `meta_key` = 'rating'
AND `comment_id` = '$sanitized_comment_id';
Я обнаружил, что наличие $результата внутри оператора if() не работает для меня.
if( $result = $wpdb->get_var($wpdb->prepare($query)) ){
Поэтому, если у вас такая же проблема, попробуйте сделать следующее:
$result = $wpdb->get_var($wpdb->prepare($query));
if( $result ){ ... }