comments_clauses
Дозволяє змінити SQL підзапити (fields, join, where, orderby, limits, groupby) при вибірці коментарів функцією get_comments() .
Використання
add_filter( 'comments_clauses', 'wp_kama_comments_clauses_filter', 10, 2); /** * Function for `comments_clauses` filter-hook. * * @param string[] $clauses An associative array of comment query clauses. * @param . * * @return string[] */ function wp_kama_comments_clauses_filter( $clauses, $query ){ // Filter... return $clauses; }
-
$pieces
(string[]) - Асоціативний масив з SQL підзапитами типу fields, join, where, orderby, limits, groupby і так далі.
-
$query
( WP_Comment_Query ) - Поточний об’єкт класу WP_Comment_Query. Класи в php передається за посиланням.
Приклади
#1 Приклад даних у фільтрі
У консолі адмінки в метабоксі “На виду” спрацьовує функція get_comments() для виведення останніх коментарів у метабоксі. Під адміністратором код запиту виглядає так:
$comments_query = array( 'number' => 25, 'offset' => 0, ); get_comments( $comments_query )
Подивимося, які дані проходять через фільтр за допомогою дебага WordPress :
add_filter( 'comments_clauses', function ( $args ) { error_log (print_r ($ args, true)); return $args; } );
Отримаємо
Array ( [fields] => wp_comments.comment_ID [join] => [where] => ( ( comment_approved = '0' OR comment_approved = '1' ) ) [orderby] => wp_comments.comment_date_gmt DESC [limits] => LIMIT 0,25 [groupby] => )
#2 wpDiscuz: сортування за популярними коментарями на основі даних WP Recall
У даному кейсі використовуються плагіни wpDiscuz та WP Recall, які дають можливість оцінювати коментарі (лайкати). Оскільки коментарі виводить wpDiscuz, то й сортування він робить на основі своїх даних, що зберігаються у метаполях під ключом wpdiscuz_votes
. На сайті використовується особистий кабінет на основі WP Recall та оцінюючи коментарі через нього, користувач отримує карму, на основі якої можна робити будь-які плюшки.
Завдання: залишити лайки від WP Recall, прибрати лайки від wpDiscuz, але залишити можливість сортувати коментарі за популярністю.
Це завдання можна вирішити двома способами
Дублювання даних
Можна копіювати дані з таблиці {$wpdb->prefix}rcl_rating_totals
плагіна WP Recall метадані для wpDiscuz. Це можна робити по кроні або на події оцінки коментаря. Робочий метод, але ми сприяємо зростанню бази даних, та й вибірки по метаполям як відомо не відрізняються швидкодією.
Підміна запиту
Що якщо вибірку по метаполі замінити на вибірку за таблицею WP Recall? Плагін wpDiscuz скупий на власні фільтри, втрутитися тут не вийде, але завдяки системному фільтру comments_clauses ми можемо це зробити!
Подивимося, які в оригіналі дані проходять через фільтр:
add_filter( 'comments_clauses', function ( $args ) { error_log (print_r ($ args, true)); return $args; } ); // Отримаємо наступне (залишив тільки те, що стосується wpDiscuz) Array ( [fields] => kw_comments.comment_ID [join] => LEFT JOIN kw_commentmeta AS `cm` ON kw_comments.comment_ID = `cm`.comment_id AND (`cm`.meta_key = 'wpdiscuz_votes') [where] => ( ( comment_approved = '0' OR comment_approved = '1' ) ) AND comment_post_ID = 93644 AND comment_type NOT IN ('wpdiscuz_sticky') AND comment_parent = 0 [orderby] => IFNULL(`cm`.meta_value,0)+0 DESC, kw_comments.`comment_ID` asc [limits] => LIMIT 0,51 [groupby] => [caller] => wpdiscuz- ) Array ( [fields] => kw_comments.comment_ID [join] => LEFT JOIN kw_commentmeta AS `cm` ON kw_comments.comment_ID = `cm`.comment_id AND (`cm`.meta_key = 'wpdiscuz_votes') [where] => ( ( comment_approved = '0' OR comment_approved = '1' ) ) AND comment_post_ID = 93644 AND comment_type IN ('wpdiscuz_sticky') AND comment_parent = 0 [orderby] => IFNULL(`cm`.meta_value,0)+0 DESC, kw_comments.`comment_ID` asc [limits] => [groupby] => [caller] => wpdiscuz- )
Побачивши патерн, можна змінити запит на наступне:
add_filter( 'comments_clauses', function ( $args ) { Global $wpdb; $is_wpdiscuz = isset( $args['caller'] ) && $args['caller'] === 'wpdiscuz-'; if ( $is_wpdiscuz && strpos( $args['join'], 'wpdiscuz_votes' ) !== false ) { $args['join'] = "LEFT JOIN {$wpdb->prefix}rcl_rating_totals AS `cm` ON $wpdb->comments.comment_ID = `cm`.object_id"; $args['orderby'] = str_replace( 'meta_value', 'rating_total', $args['orderby'] ); } return $args; }, 11); // Отримаємо Array ( [fields] => kw_comments.comment_ID [join] => LEFT JOIN kw_rcl_rating_totals AS `cm` ON kw_comments.comment_ID = `cm`.object_id [where] => ( ( comment_approved = '0' OR comment_approved = '1' ) ) AND comment_post_ID = 93644 AND comment_type NOT IN ('wpdiscuz_sticky') AND comment_parent = 0 [orderby] => IFNULL(`cm`.rating_total,0)+0 DESC, kw_comments.`comment_ID` asc [limits] => LIMIT 0,51 [groupby] => [caller] => wpdiscuz- ) Array ( [fields] => kw_comments.comment_ID [join] => LEFT JOIN kw_rcl_rating_totals AS `cm` ON kw_comments.comment_ID = `cm`.object_id [where] => ( ( comment_approved = '0' OR comment_approved = '1' ) ) AND comment_post_ID = 93644 AND comment_type IN ('wpdiscuz_sticky') AND comment_parent = 0 [orderby] => IFNULL(`cm`.rating_total,0)+0 DESC, kw_comments.`comment_ID` asc [limits] => [groupby] => [caller] => wpdiscuz- )
Зауважте, я використав у коді кілька уточнень, щоб він застосувався тільки в потрібному місці, оскільки фільтр get_comments() .
список змін
З версії 3.1.0 | Введено. |
Де викликається хук
Де використовується хук у WordPress
Використання не знайдено.