Начну с кода:
array(
"numberposts" => 10,
"orderby" => "comment_count",
"post_status" => "publish",
"order" => "DESC",
)
);
Не работает! В смысле работает, но не так, как того хочется: возвращаемые данные не сортируются по количеству комментариев (сортировка производится по дате публикации). Сразу возникает вопрос: почему? Ведь поле comment_count присутствует в таблице wp_posts. Как оказалось, всё не так просто.
Причина кроется в методе WP_Query::get_posts(). Если не вдаваться в глубокие подробности, данный метод формирует SQL-запрос для получения данных по критериям, заданным в параметрах функции get_posts() либо метода WP_Query::query().
Теперь переходим к вопросу, почему оно не работает. Всё дело в том, что в методе WP_Query::get_posts() жёстко заданы поля, по которым может осуществляться сортировка. В случае WordPress 2.6.2 эти ограничения заданы так (файл wp-includes/query.php):
- $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand');
- if ( in_array($orderby_array[$i], $allowed_keys) )
- $q['orderby'] .= (($i == 0) ? '' : ',') . $orderby;
- if ( empty($q['orderby']) )
- $q['orderby'] = "$wpdb->posts.post_date ".$q['order'];
То есть если заданного поля нет в списке разрешенных полей, то оно игнорируется; если не заданы поля для сортировки (либо они были отбракованы), то сортировка производится по дате статьи.
С причинами разобрались, теперь поговорим о способах решения.
Я вижу два способа: один из них простой ("в лоб"), другой посложнее.
- Первый способ заключается в том, что для выборки статей используется самостоятельно сконструированный запрос: например, для примера из начала статьи он мог выглядеть так:
[-]View Code MySQLДостоинства: простота (но только в случае простых запросов).SELECT *
FROM `wp_posts`
WHERE
`post_status` = 'publish' AND
`post_type` = 'post'
ORDER BY `comment_count` DESC
LIMIT 10
Недостатки: некоторые плагины (например, Disclose Secret) имеют тенденцию переписывать запросы (путём установки обработчиков фильтровposts_where_request,posts_join_requestи т.п.). Подобный "грязный хак" плагинами замечен не будет (в результате они не отфильтруют результаты). Помимо этого, использование API предпочтительнее использования прямых обращений к базе данных. - Второй способ заключается в исправлении исходного кода WordPress (путём наложения магического патча).
А вот и магический патч (кастовать на
wp-includes/query.php):
Для версии WordPress 2.6.2:[-]Download query.php.diff--- query.php.orig 2008-09-01 20:01:47.000000000 +0300
+++ query.php 2008-09-20 01:04:30.000000000 +0300
@@ -1256,7 +1256,7 @@
$q['orderby'] = "$wpdb->posts.post_date ".$q['order'];
} else {
// Used to filter values
- $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand');
+ $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order', 'parent', 'ID', 'comment_count', 'rand');
$q['orderby'] = urldecode($q['orderby']);
$q['orderby'] = addslashes_gpc($q['orderby']);
$orderby_array = explode(' ',$q['orderby']);
@@ -1275,6 +1275,9 @@
case 'rand':
$orderby = 'RAND()';
break;
+ case 'comment_count':
+ $orderby = "$wpdb->posts.comment_count";
+ break;
default:
$orderby = "$wpdb->posts.post_" . $orderby;
}Для версии WordPress 2.5.1:
[-]Download query.php.diffДостоинства: не нарушает работу сторонних плагинов.--- query.php.orig 2008-07-13 20:32:40.000000000 +0300
+++ query.php 2008-09-20 01:12:29.000000000 +0300
@@ -1238,7 +1238,7 @@
$q['orderby'] = "$wpdb->posts.post_date ".$q['order'];
} else {
// Used to filter values
- $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand');
+ $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order', 'parent', 'ID', 'comment_count', 'rand');
$q['orderby'] = urldecode($q['orderby']);
$q['orderby'] = addslashes_gpc($q['orderby']);
$orderby_array = explode(' ',$q['orderby']);
@@ -1257,6 +1257,9 @@
case 'rand':
$orderby = 'RAND()';
break;
+ case 'comment_count':
+ $orderby = "$wpdb->posts.comment_count";
+ break;
default:
$orderby = "$wpdb->posts.post_" . $orderby;
}
Недостатки: при обновлении WordPress патч придётся накладывать ещё раз (если разработчики это не исправят).

Меня зовут Владимир, я программист-фрилансер, специализирующийся на Web-программировании и програмировании под Linux.
По совместительству занимаюсь администрированием LAMP/LNMP-серверов и техническим переводом.





Можно отписать разработчикам.
Недостатки: при обновлении WordPress патч придётся накладывать ещё раз (если разработчики это не исправят).
До сих пор не исправили.
ща проверю, заранее спасибо за коды!
Патч для 2.7RC1 (тестировал на nightly build):
+++ query.php 2008-12-04 14:04:04.000000000 +0200
@@ -2023,7 +2023,7 @@
$q['orderby'] = "$wpdb->posts.post_date ".$q['order'];
} else {
// Used to filter values
- $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand');
+ $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order', 'parent', 'ID', 'comment_count', 'rand');
if ( !empty($q['meta_key']) ) {
$allowed_keys[] = $q['meta_key'];
$allowed_keys[] = 'meta_value';
@@ -2050,6 +2050,9 @@
case 'meta_value':
$orderby = "$wpdb->postmeta.meta_value";
break;
+ case 'comment_count':
+ $orderby = "$wpdb->posts.comment_count";
+ break;
default:
$orderby = "$wpdb->posts.post_" . $orderby;
}