Если вы когда то пытались настроить вывод комментов в вордпрессе задом наперед, то есть чтобы более новые комментарии были наверху, старые внизу, при этом в комментариях включена пагинация и древовидность, то вы знаете что настроек в админке не достаточно чтобы сделать все по человечески.
Приходится лезть в код. Сегодня я расскажу как настроить вывод комментариев в обратном порядке без плагинов, но с необходимостью лезть в код исходников WordPress.
Как вывести комментарии в обратном порядке.
На самом деле тут все вообще просто. Добавляем в functions.php следующий фильтр:
1 2 3 |
add_filter ('comments_array', function ($comments) { return array_reverse($comments); }); |
Обратите внимание, что функция анонимная, соотв. PHP > 5.2.
Если настройки обсуждения оставлены умолчальные, то есть Первая страница, Более ранние комментарии. То этого фильтра выше будет достаточно для вывода комментов в обратном порядке.
Но если у вас включена пагинация, то сразу вылезет проблема. После отправки комментария автор комментария будет редиректиться на не правильную страницу. На первую вместо последней и наоборот.
Исправляем функцию get_page_of_comment
Виной всему функция get_comment_link. Она генерит ссылку на комментарий по его ID. А если включена пагинация комментариев, то используется функция get_page_of_comment, для генерации номера страницы комментариев. Эти функции не используют фильтр comments_array, который использовали мы для вывода комментариев, поэтому и ссылка получается не верная. Все функции WP ( в т.ч. редирект на страницу нового комментария ), все плагины ( recent comments and etc. ), все хуки, которые используют get_comment_link для получения ссылки на комментарий будут работать не правильно.
Функция get_comment_link находятся в файле wp-includes/comment-template.php. У неё есть свой фильтр
1 |
apply_filters( 'get_comment_link', $link, $comment, $args ); |
и самым правильным бы решением было бы использование этого фильтра для переделки ссылки на коммент. Но это также бы означало дублирование функции get_page_of_comment. То есть как минимум один лишний запрос к базе на каждый вызов get_comment_link. Что не экономично.
У get_page_of_comment сейчас фильтров нет. В WP >= 4.4 get_page_of_comment также обзаведется своим фильтром, и всё можно будет сделать красивее. Однако у меня версия сильно раньше, поэтому приходится лезть в код wp-includes/comment.php, где лежит get_page_of_comment. В конец функции вносим следующие изменения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/** * Azz * Все это из-за реверсных комментов * */ // Count comments older than this one // $oldercoms = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = 0 AND comment_approved = '1' AND comment_date_gmt < '%s'" . $comtypewhere, $comment->comment_post_ID, $comment->comment_date_gmt ) ); $oldercoms = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = 0 AND comment_approved = '1' AND comment_date_gmt > '%s'" . $comtypewhere, $comment->comment_post_ID, $comment->comment_date_gmt ) ); // No older comments? Then it's page #1. // if ( 0 == $oldercoms) if ( 0 == $oldercoms || ($oldercoms - 1) < 1) return 1; // Divide comments older than this one by comments per page to get this comment's page number // return ceil( ( $oldercoms + 1 ) / $args['per_page'] ); return ceil( ( $oldercoms - 1 ) / $args['per_page'] ); /** * - Azz */ |
Закомменчены оригинальные строки кода. С таким костылем все прекрасно работает.
Но имейте ввиду, что при обновлении WP все это умрет. Ну и хардкод это совсем не правильно.
Айдар 2016-10-28
А для последних версий 4.6.ххх. это рабоатет?