按最新评论订购Wordpress帖子

时间:2009-03-30 18:25:28

标签: php mysql wordpress

我想通过最新评论订购Wordpress帖子。据我所知,使用WP_Query对象是不可能的,并且需要一个我可以轻松编写的自定义$ wpdb查询。但是,我当时不知道如何设置循环来运行这个对象。

有人可以帮忙吗?

10 个答案:

答案 0 :(得分: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

到一些变量$ query。您可以使用10或查询本身。 (我不是SQL优化忍者。)然后你的代码看起来像

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

此模式更深入by the Codex

答案 1 :(得分:3)

好的伙计们,

这里有很多很棒的答案,但显然没有人花时间去测试它们。

Hao Lian获得了第一个最好的原始答案,但不幸的是他的代码没有显示没有评论的帖子。

Keytar队长位于正确的轨道上,但他的代码会将每个帖子和附件显示为单独的结果。

以下是Captain 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

答案 2 :(得分:3)

我在函数中使用了一个更简单的原生WP部分。希望它有所帮助,有些人可以继续发展。这是一个简化版本,显示标题和&amp;该帖子的摘录以及评论内容&amp;来自最新评论帖子的作者使用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;

答案 3 :(得分: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和max(comment_date)对它们进行排序。

答案 4 :(得分: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,但一般的概念是相同的。

答案 5 :(得分:1)

Hao Lian建议的代码完美无缺,除了我们应该添加以下WHERE子句以避免使用comment_count = 0拉出POST,这种情况是由垃圾评论引起的。

要添加的WHERE子句如下:

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

添加where子句后的完整代码如下所示:

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

答案 6 :(得分: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);

答案 7 :(得分:0)

为自定义帖子类型提供3条最新评论&#39;问题&#39;无论批准如何:

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 );

答案 8 :(得分: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();

答案 9 :(得分:0)

使用Lucian的BEAUTIFUL解决方案,我需要更改/过滤现有的WP_Query以按最新评论对帖子进行排序。这是经过测试且完美运行的代码:

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

if ( $comments ) {
  foreach ( $comments as $comment ) {
    $comment_utf = strtotime($comment->comment_date);
    $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;
  }

  $query->set( 'post__in', $posts_ordered );
  $query->set( 'orderby', 'post__in' );
}