Начну с кода:

[-]
View Code PHP
return get_posts(
    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):

[-]
View Code PHP
  1. $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand');
[-]
View Code PHP
  1. if ( in_array($orderby_array[$i], $allowed_keys) )
  2.     $q['orderby'] .= (($i == 0) ? '' : ',') . $orderby;
[-]
View Code PHP
  1. if ( empty($q['orderby']) )
  2.     $q['orderby'] = "$wpdb->posts.post_date ".$q['order'];

То есть если заданного поля нет в списке разрешенных полей, то оно игнорируется; если не заданы поля для сортировки (либо они были отбракованы), то сортировка производится по дате статьи.

С причинами разобрались, теперь поговорим о способах решения.

Я вижу два способа: один из них простой ("в лоб"), другой посложнее.

  1. Первый способ заключается в том, что для выборки статей используется самостоятельно сконструированный запрос: например, для примера из начала статьи он мог выглядеть так:
    [-]
    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 предпочтительнее использования прямых обращений к базе данных.
  2. Второй способ заключается в исправлении исходного кода 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 патч придётся накладывать ещё раз (если разработчики это не исправят).
Добавить в закладки
  • del.ici.ous
  • Digg
  • Furl
  • Google
  • Simpy
  • Spurl
  • Y! MyWeb
  • БобрДобр
  • Мистер Вонг
  • Yandex.Закладки
  • Текст 2.0
  • News2
  • AddScoop
  • RuSpace
  • RUmarkz
  • Memori
  • Google Bookmarks
  • Писали
  • СМИ 2
  • Моё Место
  • 100 Закладок
  • Ваау!
  • Technorati
  • RuCity
  • LinkStore
  • NewsLand
  • Lopas
  • Закладки - IN.UA
  • Connotea
  • Bibsonomy
  • Trucking Bookmarks
  • Communizm
  • UCA
  • Slashdot
  • Magnolia
  • Blogmarks
  • Current
  • Meneame
  • Oknotizie
  • Diigo
  • Funp
  • Hugg
  • Dealspl.us
  • N4G
  • Mister Wong
  • Faves
  • Yigg
  • Fresqui
  • Care2
  • Kirtsy
  • Sphinn

Связанные записи

20
Сен
2008

Комментарии к статье «Сортировка статей по количеству комментариев в WordPress» (6)  »

  1. Макисим Покровский says:

    Можно отписать разработчикам.

  2. grang says:

    Недостатки: при обновлении WordPress патч придётся накладывать ещё раз (если разработчики это не исправят).

    До сих пор не исправили.

  3. Евгения says:

    ща проверю, заранее спасибо за коды!

  4. Vladimir says:

    Патч для 2.7RC1 (тестировал на nightly build):

    [-]
    Download query.php.diff
    --- query.php.orig      2008-11-24 08:14:40.000000000 +0200
    +++ 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;
                                    }
  5. Станислав says:

    Немного не вкурил, а нафига весь этот геморрой? Ты, что хочешь, чтобы у тебя вверху постоянно статьи с большим количеством комментов висели? Нафига?

    • Vladimir says:

      Хреновая трава… Например, для получения списка самых обсуждаемых статей в виджете.

Подписаться на RSS-ленту комментариев к статье «Сортировка статей по количеству комментариев в WordPress» Trackback URL: http://blog.sjinks.org.ua/wordpress/patches/336-sorting-posts-by-number-of-comments-in-wordpress/trackback/

Оставить комментарий к записи «Сортировка статей по количеству комментариев в WordPress»

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя