2009-03-30 3 views
4

Я хочу заказать сообщения Wordpress по последнему комментарию. Насколько мне известно, это невозможно с использованием объекта WP_Query, и для него потребуется пользовательский запрос $ wpdb, который я могу легко написать. Однако я не знаю, как настроить цикл для запуска этого объекта.Порядок размещения сообщений Wordpress по последнему комментарию

Может ли кто-нибудь помочь?

ответ

3

OK ребята,

Здесь много замечательных ответов, но, очевидно, никто не успел их протестировать.

Хао Лян получает кредит на первый лучший оригинальный ответ, но, к сожалению, в его коде не публикуются сообщения без комментариев.

Captain Keytar находится на правильном пути, но его код отображает каждое сообщение и вложение в виде отдельного результата.

Вот модифицированная версия капитана Keytar, но он ограничивает результаты в «пост» типа .. который был опубликован (чтобы избежать сквозняков !!)

select wp_posts.*, 
    coalesce(
     (
      select max(comment_date) 
      from $wpdb->comments wpc 
      where wpc.comment_post_id = wp_posts.id 
     ), 
     wp_posts.post_date 
    ) as mcomment_date 
    from $wpdb->posts wp_posts 
    where post_type = 'post' 
    and post_status = 'publish' 
    order by mcomment_date desc 
    limit 10 
+0

Просто дал этот выстрел на 3.9.1, и он работает как шарм. Благодаря! – CodeMoose

+0

Как вы можете ограничить это одной (или более) определенной категорией? – sanchy

7

Присвоить

select wp_posts.*, max(comment_date) as max_comment_date 
from $wpdb->posts wp_posts 
right join $wpdb->comments 
on id = comment_post_id 
group by ID 
order by max_comment_date desc 
limit 10 

до некоторого переменных $ запроса. Вы можете играть с помощью 10 или самого запроса. (Я не оптимизации SQL Ниндзя.) Тогда ваш код будет выглядеть примерно так

<?php 
    $results = $wpdb->get_results($query) or die('!'); 
    foreach ($results as $result): 
?> 
[insert template here] 
<?php endforeach ?> 

Эта модель покрыта более подробно by the Codex.

2

В качестве дополнения к ответу Хао Лиан, если использовать следующий запрос:

select wp_posts.*, 
coalesce(
    (
     select max(comment_date) 
     from $wpdb->comments wpc 
     where wpc.comment_post_id = wp_posts.id 
    ), 
    wp_posts.post_date 
) as mcomment_date 
from $wpdb->posts wp_posts 
order by mcomment_date desc 
limit 10 

Это смешивается в сообщениях, которые не имеют комментариев, и сортирует их по POST_DATE и макс (COMMENT_DATE).

0

Я думаю, что добавление функции max может испортить ваши результаты. MySQL не собирается вытаскивать максимум из каждого. Он вытащит максимум из полного набора. Это запрос, который будет получить вам результаты:

select wp_posts.*, comment_date 
from $wpdb->posts wp_posts 
right join $wpdb->comments 
on id = comment_post_id 
group by ID 
order by comment_date desc 
limit 10 

После этого, если вы хотите следовать WP конвенции, использовать это, а затем вы можете использовать функции, что большинство ваших шаблонов с использованием (на основе цикл):

$results = $wpdb->get_results($query) or die('!'); 
    foreach ($results as $post): 
    setup_postdata($post); 
1

кодекс предложил Hao Lian отлично работает за исключением того факта, что мы должны добавить следующее условие WHERE, чтобы избежать потянув POST с comment_count = 0, эта ситуация вызвана спам-комментариями.

ИНЕКЕ добавить следующим образом:

WHERE comment_approved = '1' AND comment_type = '' AND post_password = '' 

Полный код после добавления ИНЕКЕ Шоуда выглядеть следующим образом:

select wp_posts.*, max(comment_date) as comment_date 
from wp_posts 
right join wp_comments on id = comment_post_id 
WHERE comment_approved = '1' AND comment_type = '' AND post_password = '' 
group by ID  
order by comment_date desc 
limit 6 
3

Я использовал простой, часть встроенной функции WP.надеюсь, что это поможет, и кто-то может продолжать развиваться. Вот упрощенная версия, которая показывает заголовок & выдержки из сообщения вместе с комментарием & автор из последних комментариев с помощью get_comments.

$args = array(
     'status' => 'approve', 
     'number' => 6, 
     'order' => 'DESC' 
    ); 
    $comments = get_comments($args); 

    foreach($comments as $comment) : $count++; 

      $post_args = array(
       'post_type' => 'post', 
       'p' => $comment->comment_post_ID, 
       'posts_per_page' => 1 
       ); 

      $posts = get_posts($post_args); 

      foreach($posts as $post) : setup_postdata($post); 

       the_title(); 
       the_excerpt(); 

      endforeach; 

     echo $comment->comment_content;  
     echo $comment->comment_author; 

    endforeach; 
+1

Я тоже это делаю. Однако работает только если вы можете повторять сообщения. Скажем, 2 комментария находятся на одном и том же посту, этот пост будет повторяться в foreach. – sanchy

2

Это старый вопрос, но у меня был тот же вопрос и нашел более простой способ сделать это, поэтому я отправляю его здесь, в случае она помогает никому.

Если вы используете фильтр posts_clauses, вы можете просто изменить основной запрос и по-прежнему использовать The Loop и все обычные функции цикла.

function intercept_query_clauses($pieces) { 
    global $wpdb; 

    $pieces['fields'] = "wp_posts.*, 
    (
     select max(comment_date) 
     from " . $wpdb->comments ." wpc 
     where wpc.comment_post_id = wp_posts.id AND wpc.comment_approved = 1 
    ) as mcomment_date"; 
    $pieces['orderby'] = "mcomment_date desc"; 

    return $pieces; 
} 

add_filter('posts_clauses', 'intercept_query_clauses', 20, 1); 

Обратите внимание, что я немного изменил sql для своих целей, но общая концепция такая же.

+0

Как продолжить работу с «функциями цикла» после добавления «post_clauses»? Спасибо, что опубликовали это. – sanchy

+0

@ sanchy, вам не нужно ничего делать после posts_clauses. все функции будут работать так же, как и раньше, например. get_the_ID() и т. д. – manishie

+0

, так что это повлияет на ВСЕ мои запросы? или как выбрать, какие запросы повлиять, а какие нет? – sanchy

0

Получите 3 новые комментарии для пользовательского почтового типа «вопрос» независимо утверждении:

global $wpdb; 

$results = $wpdb->get_results(
    " 
    SELECT wp_posts.ID, MAX(comment_date) AS max_comment_date 
    FROM wp_posts 
    RIGHT JOIN wp_comments 
    ON id = comment_post_id 
    WHERE wp_posts.post_type = 'question' 
    AND wp_posts.post_status = 'publish' 
    GROUP BY ID 
    ORDER BY max_comment_date DESC 
    LIMIT 3 
    " 
); 

foreach ($results as $result) { 
    $posts_arr[] = $result->ID; 
} 

$args = array(
    'post_type' => 'question', 
    'post__in' => $posts_arr, 
    'orderby' => 'post__in', 
); 

$the_query = new WP_Query($args); 
0

Это может быть сделано путем объединения WP_Comment_Query с WP_Query, как это:

// For performance, limit the number of queried comments, 
// but make it be something big enough to account for "duplicate" posts. 

$comments_query = new WP_Comment_Query; 
$comments = $comments_query->query(array( 'number' => '100' )); 

if ($comments) { 
    foreach ($comments as $comment) { 

// You'll want to convert the dates from string to integer so you can sort them out later 
$comment_utf = strtotime($comment->comment_date); 

// Build an array of post IDs with the date of the last published comment 
$latest_comments[$comment->comment_post_ID] = $comment_utf; 
    }} 

// Sort the array by date 
arsort($latest_comments); foreach ($latest_comments as $key => $value) { $posts_ordered[] = $key; } 

// The nice thing is that WP_Query will remove duplicates by default 
$args = array ('posts_per_page'   => '10', 'post__in' => $posts_ordered, 'orderby' => 'post__in'); 
$query = new WP_Query($args); 
if ($query->have_posts()) { 
    while ($query->have_posts()) { 
     $query->the_post(); 

// Do your stuff (add the template or whatever) 

// If you want to add the comment itself, use this: 
$comments = get_comments(array('number' => '1', 'post_id' => $post->ID)); 
foreach($comments as $comment) : 
    echo $comment->comment_content; 
endforeach; 

// That's about it 
    }} 
wp_reset_postdata(); 
Смежные вопросы